-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Generating plots with many lines is slow #1039
Comments
Basically, each curve is an object where painting involves the overhead of calling a Python method, so lots of curves means lots of Python callbacks. The lines of a single curve are held in a cached There are the As for a proposed solution/improvement: I could imagine Also, I wouldn't be surprised if this has come up either here in the issues or on the mailing list. I can take a look around later to see if this has been discussed before. |
Thanks for the detailed explanation and possible solutions. One thing I noticed that may be interesting: I tried drawing the lines in real time, i.e. call I'm currently in the process of doing some measurements, but the results are pretty clear already. A little drag every 60 seconds speed up the total rendering time by a factor of 14 (!). Can that behavior be explained somehow and is that information of any use? EDIT: Benchmarks |
Not sure off-hand what would cause that. Out of curiosity I hacked together a sort of minimal implementation to test the improvement if you paint multiple paths in one paint callback like I described above. It turned out to be pretty easy but it's a just-make-it-work effort: ixjlyons@3fd61b0 Demo script: import pyqtgraph as pg
import numpy as np
pg.plot(np.arange(50), np.random.random((1000, 50)))
pg.mkQApp().exec_() So it's a lot better, but I'd still want to understand the usecase(s) to consider implementing it properly and adding it in. Usually you want different drawing options for each curve, different x values for each one, etc. You could implement a |
That's really nice, thank you for the effort. I'm probably going to do some sort of downsampling as a workaround, maybe also look into the PyQtGraph source code a bit to get an idea of what's going on (though I don't think I'm skilled enough to orientate myself and work on a |
I ran into the same issue, I hope this get improve one day :). |
For issue #1193, I made a demonstration of how to use the Since this library is about performance, maybe we should expose this more prominently in the documentation and examples or adapt the library so the user does not have to care about this, e.g. by automatically merging |
Try setting ranges of your plot:
It sped my case dramatically. Hope it helps someone. |
I was going to say some of this might be the axis contents generation. Another thing to try is #1418 which for me makes the single line case work decently well. I think we need a new issue that's a request to speed up |
@kangalioo Over 0.12.x cycle we've made some massive performance improvements to our line plot capabilities; I know it's been a while since this issue was brought up, but if you can see if current versions work to your performance needs, that would be appreciated 👍🏻 |
Thank you for the info. Performance feels unchanged, unfortunately, both on 0.12.3 and on master (bc4d40a). I ran the reproducible code snippet in the first comment. |
I made a slight modification to your code to the following for benchmark purposes: import pyqtgraph as pg
import numpy as np
app = pg.mkQApp()
lines = 1000
xs_short = np.arange(50)
ys_short = np.random.random(size=(lines, 50))
xs_long = np.arange(50_000)
ys_long = np.random.random(50_000)
win1 = pg.plot()
win2 = pg.plot()
profiler = pg.debug.Profiler(disabled=False, delayed=False)
for i in range(1000):
win1.plot(xs_short, ys_short[i,:])
profiler("Finished adding 1000 plots of 50 points")
win2.plot(xs_long, ys_long)
profiler("Finished adding 1 line of 50000 points")
pg.QtGui.QApplication.exec_() On 0.11.0 I get
On master I get:
That's puzzling why it's faster for the single line on 0.11.0; but regardless we're seeing a 2-2.5x speedup of many lines of 50 points. That said, I'm not seeing a good way to get the two down to be closer together; adding many lines has significantly more operations than just adding one bigger line. |
Oh there seems to be a misunderstanding: I was talking about performance of navigating the plots output-2021-11-13_00.20.01.mp4. |
oh! 🤦🏻 that makes a bit more sense. |
yeah we're calling Suppose this isn't a bad area to investigate with respect to performance improvements, recently there have been substantial improvements to EDIT: and now I took an extra 2 minutes to read through the comments above, yeah @ixjlyons 's solution is absolutely the correct one here; I'm not sure if a good way to incorporate this into the library without other side-effects (being able to change pen/color and so on). |
Short description
Plotting lots of curves in a single plot (>500 lines) is really slow, i.e. the
.plot(x, y)
calls take a lot of time to complete. Also, navigating the resulting plot is really sluggish.It's not just the number of data points; when plotting the same number of data points with a single line, performance is good. That's also visible in the code to reproduce
Code to reproduce
This opens two plots with the same number of data points - but the first one consists of 1000 small lines while the second plot consists of just one long line.
The above-described performance issues are clearly noticable with this code on my machine.
Expected behavior
Both generating and navigating plots with many lines should be as performant as usual in PyQtGraph.
Real behavior
Generating and navigating plots with many lines is slow and sluggish.
Tested environment(s)
Additional context
Am I using the library wrong? Or maybe there is a workaround?
The text was updated successfully, but these errors were encountered: