1

I have a pandas.DataFrame with multiple rows (1 per trade I want to inspect)

trades = pandas.read_csv(...)

I want to plot each trade on a matplotlib subplot. I create a pyplot.figure using len(trades) to create sufficient height

fig = pyplot.figure(figsize=(40,15 * len(trades)))

I then iterate over each trade and generate a plot

for i,r in enumerate(trades.iterrows()):
    _, trade = r

    start = trade.open_time  - datetime.timedelta(seconds=30)
    end   = trade.close_time + datetime.timedelta(seconds=30) 

    b = bids[start:end]
    a = asks[start:end]

    ax = fig.add_subplot(len(trades),1,i+1)

    # plot bid/ask
    ax.plot_date(b.index, b, fmt='-',  label='bid')
    ax.plot_date(a.index, a, fmt='-',  label='ask')

    # plot entry/exit markers
    ax.plot(trade.open_time,  trade.open_price,  marker='o', color='b')
    ax.plot(trade.close_time, trade.close_price, marker='o', color='r')

    ax.set_title("Trade {}".format(i+1, fontsize=10)
    ax.set_xlabel("Date")
    ax.set_ylabel("Price")

    ax.legend(loc='best', fontsize='large')

pyplot.show()

# free resources
pyplot.close(fig.number) 

This works great.

Now, however, I want to display the rendered HTML of the dataframe for the trade in question.

Since I am doing this in a jupyter notebook, from this SO answer I was able to find the following snippet which will display my dataframe in html:

t = pandas.DataFrame(trades.iloc[i]).T
IPython.display.display(IPython.display.HTML(t.to_html())

I insert this snippet into my loop.

The problem is that each trade's rendered HTML dataframe is printed one-after-the-other, and then after all of the dataframes have been printed, the plots are printed.

+-----------+
| dataframe |
+-----------+
+-----------+
| dataframe |
+-----------+
+-----------+
| dataframe |
+-----------+
+------+
|      |
| plot |
|      |
+------+
+------+
|      |
| plot |
|      |
+------+
+------+
|      |
| plot |
|      |
+------+

Given I have created a single large pyplot.figure, and I call pyplot.show() after the loop, this makes sense - inside the loop I output the dataframe HTML, and after the loop I display the plot.

Question:

How can I interleave the notebook HTML and each subplot?

+-----------+
| dataframe |
+-----------+
+------+
|      |
| plot |
|      |
+------+
+-----------+
| dataframe |
+-----------+
+------+
|      |
| plot |
|      |
+------+
+-----------+
| dataframe |
+-----------+
+------+
|      |
| plot |
|      |
+------+
Steve Lorimer
  • 27,059
  • 17
  • 118
  • 213

1 Answers1

2

I believe you need to create three separate figures and call plt.show() within the loop. Something like this (side note, I don't think one needs pyplot.close using the Jupyter notebook frontend):

trades = pandas.read_csv(...)

for i, r in enumerate(trades.iterrows()):
    _, trade = r

    start = trade.open_time  - datetime.timedelta(seconds=30)
    end   = trade.close_time + datetime.timedelta(seconds=30) 

    b = bids[start:end]
    a = asks[start:end]

    fig, ax = plt.subplots(figsize=(40, 15))

    # plot bid/ask
    ax.plot_date(b.index, b, fmt='-',  label='bid')
    ax.plot_date(a.index, a, fmt='-',  label='ask')

    # plot entry/exit markers
    ax.plot(trade.open_time,  trade.open_price,  marker='o', color='b')
    ax.plot(trade.close_time, trade.close_price, marker='o', color='r')

    ax.set_title("Trade {}".format(i+1, fontsize=10))
    ax.set_xlabel("Date")
    ax.set_ylabel("Price")

    ax.legend(loc='best', fontsize='large')

    t = pandas.DataFrame(trades.iloc[i]).T
    IPython.display.display(IPython.display.HTML(t.to_html())

    pyplot.show()
Peter Leimbigler
  • 10,775
  • 1
  • 23
  • 37