You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Figure does not show without explicit plt.show() #609
Under some circumstances when using ipympl the figure does not show up in the output area unless plt.show() is explicitly called.
At the moment the reproduction is a bit finicky. As a minimal example these cells, when executed once show a nice empty plot:
%matplotlib widget
from matplotlib import pyplot as plt
import pandas as pd
from io import StringIO
fig, axes=plt.subplots(figsize=(6, 5.5))
s="""1,2,31,2,3"""csv=StringIO(s)
df=pd.read_csv(csv)
# with this it always works:# plt.show()
When changing the line to read a more complex dataset df = pd.read_csv(file_with_1MB) the empty figure sometimes does not show up anymore. If I add an explicit plt.show() at the end the figure always appears as normal.
It is not directly tied to the larger data file though, even the example above sometimes shows the same behavior after the second cell is re-executed several times. When using %matplotlib inline no issues or errors occur.
I am somewhat certain that this behavior is a regression, as it was not occurring in earlier versions of the Jupyterlab/ipympl ecosystem (with Jupyterlab/ipympl older than approximately six months ago).
Any hints how to debug this a bit better would be appreciated.
Versions
This issues occurs with a recent jupyterlab / ipympl installation (and using Chrome 142.0.7444.60). Here, this is on Windows 11 but the issue also occurs on Linux systems.
3.13.9 | packaged by conda-forge | (main, Oct 22 2025, 23:12:41) [MSC v.1944 64 bit (AMD64)]
ipympl version: 0.9.8
Selected Jupyter core packages...
IPython : 9.7.0
ipykernel : 7.1.0
ipywidgets : 8.1.8
jupyter_client : 8.6.3
jupyter_core : 5.9.1
jupyter_server : 2.17.0
jupyterlab : 4.4.10
nbclient : 0.10.2
nbconvert : 7.16.6
nbformat : 5.10.4
notebook : 7.4.4
qtconsole : not installed
traitlets : 5.14.3
C:\tools\miniconda3\Library\envs\jupyter\share\jupyter\labextensions
jupyter-matplotlib v0.11.8 enabled ok
jupyterlab_pygments v0.3.0 enabled ok (python, jupyterlab_pygments)
@jupyter-notebook/lab-extension v7.4.7 enabled ok
@jupyter-widgets/jupyterlab-manager v5.0.15 enabled ok (python, jupyterlab_widgets)
@mbektas/notebook-intelligence v1.1.2 enabled ok (python, notebook_intelligence)
I downgraded ipykernel to 6.3.1 on two different machines / setups and could create hundreds of plots without triggering this issue. So whereas the outcome of this is only visible in ipympl the cause is does not seem to be tied to any recent change if ipympl but to ipykernel which has a number of changes regarding matplotlib in the recent releases.
As far as I can tell, ipympl has historically suffered from occasionally not displaying plots, presumably due to some race condition. It is possible that the timing changes in ipykernel 7 due to different threads, etc, make the race condition more likely.
One thing you can try is to disable the use of "Kernel comms over subshells" via JupyterLab Settings Editor. The screenshot below shows the default setting, try making it Disabled and see if that makes any difference.
I tested with an ipykernel==7.1.0 by generating tens of figures again. With "Kernel Comms over subshells" set to "One subshell per comm-target" after a few figures first the figure does not show up and the output only comprises of [<matplotlib.lines.Line2D at 0x198034cc690>]. When re-executing the cell again the kernel appears to have crashed or stalled, only showing the * and not continuing with the next cell. At this point only a restart helps.
When setting "Kernel Comms over subshells" to disabled the error goes away completely. Plots show up and the kernel does not stall or crash.
Bad news from me: I did disable use of "Kernel comms over subshells" and although things worked for a bit longer, I still eventually got into a state where every cell claimed it was busy, nothing was making progress, and even interrupting and restarting the kernel did not help. Restarting JupyterLab itself was necessary, which in my setup means shutting down and respawning the Lab container.
I strongly suspect there's a nasty race condition somewhere down in the threading code.
ipykernel 7 fires IPython's post_execute event while handling a comm_msg on a subshell, under the comm_msg's parent header. flush_figures runs there, displays the queued figure with parent_header pointing at the comm_msg instead of the cell's execute_request, and the frontend — which routes output to cells by that id — drops it. The queue is then empty, so the cell's own post_execute displays nothing.
That fits the symptoms reported here: the first figure of a session is fine, a figure already on screen keeps a comm busy so the next one disappears, it is more likely with slower cells, and %matplotlib inline is unaffected because it creates no comms.
Minimal reproducer with no matplotlib involved, plus 7.3.0-vs-6.31.0 traces: ipython/ipykernel#1564
Workarounds that fixed it for me: pip install "ipykernel<7", or set Settings -> Kernels -> Kernel Comms over subshells to Disabled in JupyterLab.
If ipykernel considers this behaviour intended, ipympl could work around it by capturing the parent at figure-creation time, or by skipping the flush when post_execute fires outside an execute_request.
Activity
jokasimr commentedon Nov 17, 2025
I had similar problems and downgrading
ipykernelto<7made those issues go away.asteppke commentedon Nov 19, 2025
@jokasimr Thank you very much for this hint!
I downgraded
ipykernelto6.3.1on two different machines / setups and could create hundreds of plots without triggering this issue. So whereas the outcome of this is only visible inipymplthe cause is does not seem to be tied to any recent change ifipymplbut toipykernelwhich has a number of changes regarding matplotlib in the recent releases.ianthomas23 commentedon Nov 19, 2025
As far as I can tell, ipympl has historically suffered from occasionally not displaying plots, presumably due to some race condition. It is possible that the timing changes in ipykernel 7 due to different threads, etc, make the race condition more likely.
One thing you can try is to disable the use of "Kernel comms over subshells" via JupyterLab Settings Editor. The screenshot below shows the default setting, try making it Disabled and see if that makes any difference.
asteppke commentedon Nov 19, 2025
@ianthomas23 Thank you for looking into this!
I tested with an
ipykernel==7.1.0by generating tens of figures again. With "Kernel Comms over subshells" set to "One subshell per comm-target" after a few figures first the figure does not show up and the output only comprises of[<matplotlib.lines.Line2D at 0x198034cc690>]. When re-executing the cell again the kernel appears to have crashed or stalled, only showing the*and not continuing with the next cell. At this point only a restart helps.When setting "Kernel Comms over subshells" to disabled the error goes away completely. Plots show up and the kernel does not stall or crash.
ianthomas23 commentedon Nov 19, 2025
@asteppke Thanks for checking.
So the recommended workaround is to disable use of "Kernel comms over subshells" whilst this is investigated further.
athornton commentedon May 7, 2026
Bad news from me: I did disable use of "Kernel comms over subshells" and although things worked for a bit longer, I still eventually got into a state where every cell claimed it was busy, nothing was making progress, and even interrupting and restarting the kernel did not help. Restarting JupyterLab itself was necessary, which in my setup means shutting down and respawning the Lab container.
I strongly suspect there's a nasty race condition somewhere down in the threading code.
202601: constrain ipykernel due to plotting issue
PatVolp commentedon Sep 21, 2026
I think I have the root cause for this.
ipykernel 7 fires IPython's post_execute event while handling a comm_msg on a subshell, under the comm_msg's parent header. flush_figures runs there, displays the queued figure with parent_header pointing at the comm_msg instead of the cell's execute_request, and the frontend — which routes output to cells by that id — drops it. The queue is then empty, so the cell's own post_execute displays nothing.
That fits the symptoms reported here: the first figure of a session is fine, a figure already on screen keeps a comm busy so the next one disappears, it is more likely with slower cells, and %matplotlib inline is unaffected because it creates no comms.
Minimal reproducer with no matplotlib involved, plus 7.3.0-vs-6.31.0 traces: ipython/ipykernel#1564
Workarounds that fixed it for me: pip install "ipykernel<7", or set Settings -> Kernels -> Kernel Comms over subshells to Disabled in JupyterLab.
If ipykernel considers this behaviour intended, ipympl could work around it by capturing the parent at figure-creation time, or by skipping the flush when post_execute fires outside an execute_request.