Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable plotting in same notebook cell which imports matplotlib.pyplot #11916

merged 2 commits into from Nov 5, 2019


Copy link

@benjimin benjimin commented Oct 17, 2019

This fixes a bug for Jupyter notebooks, that plot commands often do not display until the second time their cell is executed. jupyter/notebook#3691

Specifically, inline display of plots was broken for the first cell which imports matplotlib.pyplot, but does works in subsequent cells (or even if the same cell is evaluated a second time). This particularly affected libraries that lazily import matplotlib, such as xarray:

In [1]: import xarray, numpy as np
In [2]: x = xarray.DataArray(np.random.random((5,5)))
In [3]: x.plot() # did not work
In [4]: x.plot() # did work

The problem related to circular imports between matplotlib and ipython. The import of the matplotlib.pyplot module executes a call to IPython.core.pylabtools:activate_matplotlib which in turn imports matplotlib.pyplot (while it is still only partially initialised e.g. the matplotlib module may not yet have a pyplot attribute). By using a slightly different import syntax it is possible to avoid causing an exception here.

Note, there is also a partial work-around in ipykernel.pylab.backend_inline:_enable_matplotlib_integration which catches the import/attribute error and in that case reschedules activate_matplotlib until after the cell finishes executing (i.e. after import completes). The problem was that it was late to schedule flush_figures (as the event is already triggering before the callback gets registered), which is why plotting only worked in subsequent cell evaluations.

Tested on python 3.6.7.

Copy link
Contributor Author

@benjimin benjimin commented Oct 17, 2019

I'd also like to add a regression test, but unsure how to programmatically create a separate kernel instance that thinks it supports inline plotting (so that I can test whether the kernel calls flush_figures after the same cell that runs import matplotlib.pyplot)?

@minrk minrk merged commit 7c93853 into ipython:master Nov 5, 2019
2 checks passed
Copy link

@minrk minrk commented Nov 5, 2019

Thanks for the fix! A test like you are describing would probably be best in the ipykernel repo, which has the inline backend and eventloop setup

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet
None yet

Successfully merging this pull request may close these issues.

None yet

3 participants