avoid repaint when using a cursor

74 views
Skip to first unread message

Daniel Hrisca

unread,
Feb 10, 2022, 2:25:59 AM2/10/22
to pyqtgraph
Hello,

for my plots I use an Infinite vertical line to simulate a Cursor. When the cursor is dragged by the user the instantaneous signal values at that timestamp are reported to the user in a different widget. 

My issue is that with a large signal count (let's say 4000 signals) moving the cursor triggers a complete repaint that is really slow to execute.

Is there some way to have like an overlay where the bottom layer contains the signal curves (and thus dos not require a repaint when the cursor is moved) and the top layer contains the Cursor?

Thanks! 

Ognyan Moore

unread,
Feb 10, 2022, 10:22:51 AM2/10/22
to pyqt...@googlegroups.com
Hi,

For this sort of thing, the trick is to get all the lines to do a repaint in one go instead of repainting one line at a time.

A while back, Kenneth Lyons did a proof of concept to make that work (note it requires altering some library code); but I would start with something like this first: 


--
You received this message because you are subscribed to the Google Groups "pyqtgraph" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pyqtgraph+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/pyqtgraph/6417a3ef-2c79-48cb-a4f6-3d5f5fcc982an%40googlegroups.com.

Daniel Hrisca

unread,
Feb 11, 2022, 2:05:44 AM2/11/22
to pyqtgraph
It's not clear to me how the changes made in PlotCurveItem could impact a PlotWidget with multiple curves. 

Daniel Hrisca

unread,
Feb 11, 2022, 6:25:58 AM2/11/22
to pyqtgraph
I wonder if this is possible: 
* have multiple layers of graphical items, each backed by a pixmap
* changing an graphical item would only trigger the repainting of the pixmap for the corresponding layer
* the final paint would be a composition of the pixmaps

This would allow for faster updates in the cases where only a few items are changed (shifted curves, cusor, etc.).

In my use case there is a single curve per viewbox, and the viewboxes are X-linked, so a Y zoom change would not affect the rest of the viewboxes. I don't know how the ideas above impact having multiple curves per viewbox. 

Daniel Hrisca

unread,
Mar 9, 2022, 6:39:41 AM3/9/22
to pyqtgraph
After days of tinkering and search I have come up with the following solution:
1. derive new classes for the Cursor (based on InfiniteLine) and Region (based on LinearRegion) were the paint method had an argument that prevents painting by default (see https://github.com/danielhrisca/asammdf/blob/1a4ee1bad931c4a338dd12db2577914797785d5b/asammdf/gui/widgets/cursor.py#L36)
2. let the default painting of the PlotWidget with the axes and curves, then grab the widget into a QPixmap (see https://github.com/danielhrisca/asammdf/blob/1a4ee1bad931c4a338dd12db2577914797785d5b/asammdf/gui/widgets/plot.py#L4251)
3. once the QPixmap is available the  PlotWidget painting will first paint the  QPixmap  and after that the Cursor or Region on top of it

With this approach I can get close to 60FPS (painting + other stuff related to the cursor movement) compared to ~5s / cursor movement event if the Plot need to be repainted from scratch (tested with 1000 curves).

Reply all
Reply to author
Forward
0 new messages