pyqtgraph processEvents

2,005 views
Skip to first unread message

nervenzelle

unread,
Oct 25, 2012, 12:32:12 PM10/25/12
to pyqt...@googlegroups.com
Good evening,

I'm trying to update a pyqtgraph plot in a loop. The problem is, that the plot window remains white. I suppose that this is because of the time.sleep() I also use in the loop and the program doesn't have the time to paint the plot. Is there a possibility to use the pyqt function processEvents() in order to solve this issue? Unforunately pyqtgraph.GraphicsWindow is unaware of this function ;)

I'd be very glad about any kind of help. Greetings, nervenzelle

Luke Campagnola

unread,
Oct 25, 2012, 2:40:15 PM10/25/12
to pyqt...@googlegroups.com
On Thu, Oct 25, 2012 at 12:32 PM, nervenzelle <batterie...@googlemail.com> wrote:
I'm trying to update a pyqtgraph plot in a loop. The problem is, that the plot window remains white. I suppose that this is because of the time.sleep() I also use in the loop and the program doesn't have the time to paint the plot. Is there a possibility to use the pyqt function processEvents() in order to solve this issue? Unforunately pyqtgraph.GraphicsWindow is unaware of this function ;)

You are correct in your assessment of the problem. There are a few ways you can solve this:

   1) The standard procedure in event-based programming is to execute long loops using a timer (in this case, QTimer). Rather than looping directly, allow Qt to execute each iteration of the loop for you. This will also allow Qt to redraw its window and respond to user input in between iterations of the loop.
   2) If you prefer to keep your loop intact, you can indeed call processEvents() at each loop iteration, but note that this is a static method of QApplication, so the correct way to invoke it is QApplication.processEvents().
   3) It is also possible to directly request that any QWidget draw immediately by calling its repaint() method. This can provide better performance but has the drawback that no other widgets will be redrawn and user input events will not be processed. 


Luke

nervenzelle

unread,
Oct 25, 2012, 3:16:11 PM10/25/12
to pyqt...@googlegroups.com
Thank you very much for your almost immediate answer!

I already got the hint about QApplication.processEvents() but there was something about your post which let me succeed with my last attempt. :) Thanks a lot about that. Unfortunately, you're right about bad performance with this solution. I'm now working on the repaint method. It is absolutely no problem that only a single widget is redrawn, that is everything I need. Bad news: I'm creating a plot with the following code (this works perfectly):

        window=pyqtgraph.GraphicsWindow(...)
        plot1=self.window.addPlot(0,  0)
        ...
        plot1.plot(data1, data2)


But the following lines only end in a white window:

        while True:
 
           time.sleep(5)
            ...
            window.repaint()

Luke Campagnola

unread,
Oct 25, 2012, 6:24:02 PM10/25/12
to pyqt...@googlegroups.com
On Thu, Oct 25, 2012 at 3:16 PM, nervenzelle <batterie...@googlemail.com> wrote:
Unfortunately, you're right about bad performance with this solution.

I expect the performance difference to be quite minimal unless you have a lot of other events being processed in your application (which it sounds like is not the case). So probably you should look elsewhere to improve performance. Can you tell me 1) how many points you are plotting,  2) how rapidly, and 3) what style options you are using (line widths, point symbols?). 
 
I'm now working on the repaint method. It is absolutely no problem that only a single widget is redrawn, that is everything I need. Bad news: I'm creating a plot with the following code (this works perfectly):

        window=pyqtgraph.GraphicsWindow(...)
        plot1=self.window.addPlot(0,  0)
        ...
        plot1.plot(data1, data2)


But the following lines only end in a white window:

        while True:
 
           time.sleep(5)
            ...
            window.repaint()


I'm just guessing, but you may need to call processEvents() at least once before painting to allow Qt to deliver resizeEvents to its widgets, but I've only ever used repaint() for benchmarking purposes.. you should be able to get good performance without it.


Luke

nervenzelle

unread,
Oct 28, 2012, 2:40:09 PM10/28/12
to pyqt...@googlegroups.com
Sorry, but real-life interfered ;)

I'm not plotting that many points (<70) about every second. The style options are more or less the default ones. I don't expect any performance problems there. The symptom is mainly the lack of reaction when dragging and resizing windows for several seconds. It isn't nescessary for the actual purpose of the program but suboptimal during presentations. Maybe I should try a better notebook. ;)

Unless you have another useful idea in mind the main issue could be regarded as solved. Thanks a lot!

Luke Campagnola

unread,
Oct 28, 2012, 2:46:44 PM10/28/12
to pyqt...@googlegroups.com
On Sun, Oct 28, 2012 at 2:40 PM, nervenzelle <batterie...@googlemail.com> wrote:
I'm not plotting that many points (<70) about every second. The style options are more or less the default ones. I don't expect any performance problems there. The symptom is mainly the lack of reaction when dragging and resizing windows for several seconds. It isn't nescessary for the actual purpose of the program but suboptimal during presentations. Maybe I should try a better notebook. ;)

At that speed you should have absolutely no performance problems, even on old machines. 
One common mistake is to repeatedly call PlotItem.plot(data) and not realize that this does not clear out the old plot(s). Over time, plots can add up and slow things down (but at 70 points per second, even that should take a very long time). 

I can probably provide better help if you send me an example I can run.

Luke

 

nervenzelle

unread,
Oct 29, 2012, 3:56:02 PM10/29/12
to pyqt...@googlegroups.com
Hi,

I've attached a very shortened version of my project which uses random numbers instead of about a hundred lines of code ;)

while the application runs quite smooth when left alone there still are lags when dragging and resizing the window. (only tested on one computer, I have to admit)

This probably is more a problem of pyqt than pygtgraph?

Dominic
main.py

Luke Campagnola

unread,
Oct 30, 2012, 12:06:44 PM10/30/12
to pyqt...@googlegroups.com
Yeah, I've seen this on Windows machines. It appears to be an issue with either Windows or Qt+Windows. There are a few comments like these scattered around, but no solutions that I see (aside from 'use Linux instead'): 

Luke

Luke Campagnola

unread,
Oct 30, 2012, 12:18:19 PM10/30/12
to pyqt...@googlegroups.com
[Sorry, accidentally sent the last message before I had finished writing it]

On Mon, Oct 29, 2012 at 3:56 PM, nervenzelle <batterie...@googlemail.com> wrote:
I've attached a very shortened version of my project which uses random numbers instead of about a hundred lines of code ;)

while the application runs quite smooth when left alone there still are lags when dragging and resizing the window. (only tested on one computer, I have to admit)


On Linux, moving the window in your example has no effect on performance but resizing the window is very slow.
If you replace the loop at the end of your example with this code:

timer = Qt.QTimer()
timer.timeout.connect(update)
timer.start(1000)
Qt.QApplication.exec_()

This improves performance during resizing dramatically since it allows Qt to respond to resize events much more rapidly (whereas in your example, it is restricted to responding only once per second). 

As I mentioned previously, though, you might be experiencing different problems on Windows in addition to this one.

Luke

nervenzelle

unread,
Oct 30, 2012, 2:47:29 PM10/30/12
to pyqt...@googlegroups.com
hey, you're right, this certainy works much smoother than my attempt :)
This is absolutely sufficient.


Can I place pyqtgraph-windows with absolute coordinates on screen? Then I wouldn't have to move the window at all. QtGui.QWidget knows a method move()...



Many thanks again by a relieved Dominic ;)

Luke Campagnola

unread,
Oct 30, 2012, 4:15:27 PM10/30/12
to pyqt...@googlegroups.com
On Tue, Oct 30, 2012 at 2:47 PM, nervenzelle <batterie...@googlemail.com> wrote:
hey, you're right, this certainy works much smoother than my attempt :)
This is absolutely sufficient.


Can I place pyqtgraph-windows with absolute coordinates on screen? Then I wouldn't have to move the window at all. QtGui.QWidget knows a method move()...

I think you want QWidget.setGeometry(), but it needs to be called on the window, so:

plot.window().setGeometry(x, y, w, h)

 
Reply all
Reply to author
Forward
0 new messages