3

In an IPython/Jupyter notebook I have a situation similar to the following pseudo code:

cell 1:
run some computation
plot several plots (separate figures)

cell 2:
run some computation
plot several plots (separate figures)

This is working nicely, except for one annoyance. When I run both cells sequentially (Shift-enter, Shift-enter), the computation in the second cell starts running before the plots in the first cell are rendered and the plots for both cells are only rendered after the computation for both cells is completed. Just to be clear, the figures for the plots in the first cell are created immediately after the computation in the first cell is completed, but they remain empty until after the computation in the seconds cell is also completed.

This would not be a huge problem except that if there is an uncaught exception in the second cell, which kills the computation for some reason, the plots in the first cell will never be rendered and the figures will remain empty.

I am looking for a way to instruct matplotlib or jupyter (I am not sure where the issue is) at the end of cell 1 - finish rendering all outstanding plots before continuing code execution.

I am using the %matplotlib notebook magic and matplotlib 1.5.3.

Thanks!

Thomas K
  • 39,200
  • 7
  • 84
  • 86
odedbd
  • 2,285
  • 3
  • 25
  • 33

1 Answers1

1

For anyone running into this problem, using matplotlib 1.5.3 and jupyter-client 4.3 I am able to force draw using: plt.gcf().canvas.draw().

For rendering multiple figures that were broken due to an exception in some previous cell, I found this to work:

for fig_num in plt.get_fignums():
    plt.figure(fig_num).canvas.draw()
odedbd
  • 2,285
  • 3
  • 25
  • 33
  • Using `canvas.draw()` gets me most of the way, but the layout of the figure is not properly set until all cells are drawn. This causes part of the figures to not be visible at first, as they are drawn partly outside of their bounding box. – Erlend Magnus Viggen May 14 '19 at 14:30
  • As a follow-up to my previous comment, I found a workaround to that problem by calling `fig.tight_layout()` and `fig.subplots_adjust(right=0.85, bottom=0.2)` after the figure has been set up. While you might need to adjust the exact values, this should pad the right and bottom parts of the figure so that everything is visible. For the case specified in the question, I'd say adding these two lines for all of your plots is too much of a hassle. However, the workaround works well when redrawing a figure dynamically while a cell is processing. – Erlend Magnus Viggen May 14 '19 at 15:22