3/14/2023 0 Comments Live scatter plot matplotlib![]() ![]() Matplotlib by default values quality over performance. In conclusion, I am quite impressed with the flexibility of Matplotlib. This is equally fast as the code above without any visual artifacts, but breaks if you resize the plot. There is also a way of drawing the complete figure once and copying the complete but empty background, then reinstating that and only plotting a new line on top of it. The axes in particular are quite expensive. ![]() If you draw all of them, you get roughly the same performance as (). To draw the axes, use ax.draw_artist(ax.xaxis) and ax.draw_artist(ax.yaxis). To also draw the spines, use for spine in ax.spines.values(): ax.draw_artist(spine). Note that since we are only redrawing the background and the line, some detail in the axes will be overwritten. Five hundred times per second! Frankly, this is quite amazing! This now plots about 500 frames per second. Note that you have to add () to copy the newly rendered lines to the drawing backend. To only redraw these, the code now looks like this: That is, at least the background and the line. What we can do here is to selectively draw only the parts that are actually changing. the line, as returned from the plot() function.For a simple plot like this, the artists are: Those artists can be accessed using ax.get_children(). What this really is doing is drawing all the artists contained in the ax. The only thing left to optimize now is thus (). flush_events() just runs the Qt event loop, so there is probably nothing to optimize there. Note that the call to show() mentioned earlier can be omitted since the figure is already on screen. Which now plots about 40 frames per second. ![]() To add insult to injury, it even insists on sleeping at least one hundredth of a second, which actually explains the profiler output of 0.167 seconds of sleep() for 15 calls very well. The default implementation of _event_loop() then calls _events(), then sleeps for the requested time. Then again, I was wondering if using pause really was a great idea for performance…Īs it turns out, pause() internally calls (), then plt.show(), then _event_loop(). Delving deeper into the profiler shows that this is indeed happening in the call do pause(). The one function that uses the biggest chunk of runtime is sleep(), of all things. Profiling this yields some interesting results: Thus, they won't change their limits based on the data any more. The downside is that the axes are not re-scaled any longer when the data changes. Instead of calling clear() and then plot(), thus effectively deleting everything about the plot, then re-creating it for every frame, we can keep an existing plot and only modify its data: One thing that really takes time here is creating all the axes and text labels over and over again. But then, this is really the simplest case possible, so ten frames per second in the simplest case probably means bad things for not so simple cases. If you are not using the Qt4Agg backend, draw() is supposedly the correct choice.įor a single plot, ten plots per second is not terrible. The correct way to do this is to use draw() instead, but due to a bug in the Qt4Agg backend, you can't use it there. I am using pause() here to update the plot without blocking. On my machine, I get about 11 plots per second. ![]()
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |