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
merged 2 commits into from Nov 5, 2019

Conversation

@benjimin
Copy link
Contributor

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.

@benjimin

This comment has been minimized.

Copy link
Contributor Author

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)?

@benjimin benjimin force-pushed the benjimin:bugfix branch from 5e59669 to efbef07 Oct 17, 2019
@minrk minrk merged commit 7c93853 into ipython:master Nov 5, 2019
2 checks passed
2 checks passed
continuous-integration/appveyor/pr AppVeyor build succeeded
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details
@minrk

This comment has been minimized.

Copy link
Member

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

@Carreau Carreau added this to the 7.10 milestone Nov 12, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can’t perform that action at this time.