ipympl
ipympl copied to clipboard
plt.pause uses removed `start_event_loop_default` API
As the title suggests, attempting to pause through matplotlib currently raises an error. The minimum working example is:
%matplotlib widget
from matplotlib import pyplot as plt
plt.plot([1,2,3])
plt.pause(1)
plt.plot([3,2,1])
plt.close()
This raises an attribute error trying to call FigureCanvasBase.start_event_loop_default. A little googling suggests this function has been removed since version 3.0.
Taking inspiration from #17, I guess the simplest get around is using time.sleep but is there a better solution?
Thanks for your help.
I'm not sure sleep works for me because in my case I want to pause for matplotlib event handling.
In my case I have code running in a loop that needs to periodically update the plot and get mouse events from the plot.
Is this a problem in jupyter-matplotlib or in matplotlib in general?
This is an issue trying to integrate multiple event loops (see https://github.com/matplotlib/matplotlib/pull/4779 for very long discussion (I really need to finish that PR)).
plt.pause
needs to a) block user code so that there is a 1s gap between when your two plt.plot
calls are made, but b) not block what ever is backing your UI / background tasks.
@robtovey Hi,I have the same problem as you ,did you have some better solution? thanks for your help!
Hi @xilunaJumma, I'm afraid not. If I want to use dynamic plotting properly then I normally make a video but then I use the Agg backend anyway. Unfortunately I haven't found a particularly elegant way to replicate a 'slideshow' effect inside jupyter without having to change the backend.
Same problem here. A practical solution, to run an animation using the plt.pause() methodology, could be:
- Save the code in a python script.
- Run the terminal in Jupyter.
- Open the folder from where the .py script is.
- Run the command (python 3.x): python3 your_animation_script.py
It will open a pop-up window showing the animation.
Hello All,
Is there any solution to this issue? I encountered this problem when I was implementing a GUI embedded in a jupyter notebook. Here, a more detailed explanation can be found.
Thanks for your help.
It seems that the nbAgg backend just doesn't implement these methods: https://github.com/matplotlib/matplotlib/blob/bb71b00ac1a16c41054c2a5907d04f65da3e8565/lib/matplotlib/backends/backend_nbagg.py#L144
Inspired by that I found that just commenting these lines out: https://github.com/matplotlib/ipympl/blob/8de137336b3775e956db0c77133b581d1a4a9930/ipympl/backend_nbagg.py#L254-L258 got rid of the error. The result is that no python code runs until the end of the pause period. Happily the browser event loop keeps running so that seems to satisfy both conditions of:
plt.pause needs to a) block user code so that there is a 1s gap between when your two plt.plot calls are made, but b) not block what ever is backing your UI / background tasks.
Though I can't say I fully understand what the expected behavior of plt.pause is, so this very well may have broken something else.
Removing those methods is an acceptable fix. It will not fallback to the implementation in FigureCanvasBase
. It might be better to write a specific version of this for ipympl that just sleeps (or sleeps with a lower polling frequency), but removing the methods is :+1: for now.
Has there been any effort to create a more permanent fix? I am currently having this issue with my jupyter notebooks.
@Michael-Equi I think my proposed solution should work pretty well as a permanent fix. The issue is that it has remained as "proposed" and never made it all the way to implemented