-
-
Notifications
You must be signed in to change notification settings - Fork 7.7k
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
plt.pause() with threading is extremely slow for MacOSX backend #5675
Comments
can you try the fix in #5562? |
There are two issues here:
plt.draw()
plt.pause(0.001)
time.sleep(1) The following code works as intended: import random
import time
import threading
import matplotlib.pyplot as plt
class Plot:
def __init__(self):
plt.ion()
plt.show()
self.start = time.time()
self.xdata = []
self.ydata = []
self.running = None
self.axis = plt.figure().add_subplot(111)
self.line, = self.axis.plot([])
threading.Thread(target=self.worker).start()
def worker(self):
for _ in range(100):
self.xdata.append(len(self.xdata))
self.ydata.append(random.random())
self.axis.set_xlim(0, len(self.xdata))
self.axis.set_ylim(0, max(self.ydata))
self.line.set_data(self.xdata, self.ydata)
time.sleep(0.1)
print(time.time() - self.start)
if __name__ == '__main__':
Plot() |
To explain how this works:
|
Thanks for the explanation. I tried the updated script but the window does not get redrawn at all. |
I am using matplotlib 1.5.0. Run with "python -i script.py"; "python script.py" won't work. |
Okay, I can confirm it works without problems in interactive mode. Thanks for the clarification. |
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 See my comment to @tacaswell above. That should do it. |
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 |
Stale does propagate, the question is if anything at the top is listening. For non-interactive backends (ex Agg) the One possible solution to this is to make the OSX backend's 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.
|
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.
Profiling revealed that by far the most time is spent in
start_event_loop
of_macosx.FigureCanvas
.Possibly related: #5251
The text was updated successfully, but these errors were encountered: