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
plt.pause() with threading is extremely slow for MacOSX backend #5675
Here is a minimal example where a worker produces a sequence that's plotted every second by the main thread. Between the draw calls, the main thread pauses for 0.001s to update the GUI and sleeps for 1s. This takes 10 seconds. When pausing for 1s and sleeping for 0.001s instead, I would expect this to run in about the same time. However, it takes 70 seconds.
To explain how this works:
The event loop starts running in the main thread as soon as the MacOSX backend is imported.
Then we start the following cycle:
The event loop is sitting in the main thread, waiting for something to happen;
The worker thread calls set_xlim, set_ylim, set_data, which will invalidate the canvas;
The event loop notices that the canvas is invalidated, triggering a redraw in the main thread.
Thanks for the explanation. I tried the updated script but the window does not get redrawn at all.
Which version of matplotlib are you referring to? (I am using 1.5.0)
The reason it doesn't work in non-interactive mode is probably that the set_xlim, set_ylim, set_data doesn't invalidate the canvas in non-interactive mode.
@tacaswell Perhaps stale should always propagate irrespective of whether matplotlib is interactive or non-interactive.
As I understand it, your comment suggested a change in matplotlib. Do you have a fix for users that works right now? I thought about invalidating the canvas with something like fig.canvas.draw_idle() but I can't test on Mac right now.
Stale does propagate, the question is if anything at the top is listening.
For non-interactive backends (ex Agg) the draw_idle is not (and can not be) asynchronous (it is re-entrant so stale flags that arise in a draw do not trigger recursive draws).
One possible solution to this is to make the OSX backend's Figure always invalidate it's canvas independent of the interactive state.
Having said that, that might be the right place to put all of this logic (backend dependent).
This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!
It seems like there is still some work here to do. This only seems to work as expected on the qt5agg backend for me.
tk: runtime error with calling draw_idle() from off the main thread. (Stemming from setting the figure stale during the xlim updates)
macosx: no canvas updates, it seems like the loop isn't receiving and processing the draw_idle() timers. The canvas is somewhat disassociated with the events. For example, after the worker thread is done, the mouse hovers all work as expected, but the draws never get triggered and update. However, if you click the subplot tool and mess around with those settings, then the Agg canvas is updated and redrawn, but going back to the pan/zoom tools does nothing again, so those events don't seem to go back to the Agg redraws.
Activity
jenshnielsen commentedon Dec 14, 2015
can you try the fix in #5562?
mdehoon commentedon Dec 15, 2015
There are two issues here:
The following code works as intended:
mdehoon commentedon Dec 15, 2015
To explain how this works:
The event loop starts running in the main thread as soon as the MacOSX backend is imported.
Then we start the following cycle:
koogle commentedon Dec 15, 2015
Thanks for the explanation. I tried the updated script but the window does not get redrawn at all.
Which version of matplotlib are you referring to? (I am using 1.5.0)
mdehoon commentedon Dec 16, 2015
I am using matplotlib 1.5.0. Run with "python -i script.py"; "python script.py" won't work.
koogle commentedon Dec 16, 2015
Okay, I can confirm it works without problems in interactive mode. Thanks for the clarification.
mdehoon commentedon Dec 16, 2015
The reason it doesn't work in non-interactive mode is probably that the set_xlim, set_ylim, set_data doesn't invalidate the canvas in non-interactive mode.
@tacaswell Perhaps stale should always propagate irrespective of whether matplotlib is interactive or non-interactive.
danijar commentedon Dec 19, 2015
Thanks @mdehoon for the example @koogle for testing. What would be the right way to make your example work in non-interactive mode?
mdehoon commentedon Dec 21, 2015
@danijar See my comment to @tacaswell above. That should do it.
danijar commentedon Dec 21, 2015
As I understand it, your comment suggested a change in matplotlib. Do you have a fix for users that works right now? I thought about invalidating the canvas with something like
fig.canvas.draw_idle()but I can't test on Mac right now.tacaswell commentedon Dec 21, 2015
Stale does propagate, the question is if anything at the top is listening.
For non-interactive backends (ex Agg) the
draw_idleis not (and can not be) asynchronous (it is re-entrant so stale flags that arise in adrawdo not trigger recursive draws).One possible solution to this is to make the OSX backend's
Figurealways invalidate it's canvas independent of the interactive state.Having said that, that might be the right place to put all of this logic (backend dependent).
github-actions commentedon Mar 20, 2023
This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!
greglucas commentedon Mar 21, 2023
It seems like there is still some work here to do. This only seems to work as expected on the qt5agg backend for me.
tk: runtime error with calling draw_idle() from off the main thread. (Stemming from setting the figure stale during the xlim updates)macosx: no canvas updates, it seems like the loop isn't receiving and processing the draw_idle() timers. The canvas is somewhat disassociated with the events. For example, after the worker thread is done, the mouse hovers all work as expected, but the draws never get triggered and update. However, if you click the subplot tool and mess around with those settings, then the Agg canvas is updated and redrawn, but going back to the pan/zoom tools does nothing again, so those events don't seem to go back to the Agg redraws.