0

I am implementing a pyqtgraph based ECG display application.

It updates 24 subplots in a grid. Each subplot has 4 ECG channels and each channel has a corresponding buffer size of 2500 integers.

A dedicated UDP thread fetches the data from network and writes to python queues and the queues are read by a functions which is periodically called by QTimer. Some relevant code snippets:

win = pg.GraphicsWindow()

#Create the GRID using the constructor and win.nextRow
for x in range(0, (config_data.num_of_devices / config_data.gridwidth)):
    for y in range(0, config_data.gridwidth):
        devicenum = (config_data.gridwidth * x) + y
        devicehandle[devicenum] = Deviceplot(
            devicenum, tpen, dataq[devicenum], win, config_data)
    win.nextRow()


class Deviceplot(object):

    def __init__(self, device, tpen, dataqueue, win, config_data):
        self.p = win.addPlot()
        self.curve1 = self.p.plot(self.data1, pen=self.tpen)

def update():
    for x in range(0, config_data.num_of_devices):
        devicehandle[x].getdata()
        devicehandle[x].update1()
        devicehandle[x].update2()
        devicehandle[x].update3()
        devicehandle[x].update4()

timer = pg.QtCore.QTimer()
timer.timeout.connect(update)
timer.start(100)  

The timer is supposed to fire every 100ms. But the timer periodicity is more than 100ms when I checked. Hence the plots feels slower. The update functions processing time is less than 100ms. Luke at pyqtgraph's google groups says that, the extra time is taken for repainting the GUI.

I enabled a click handler which maximized a single plot and hides all other plots. Now the timer fires properly. my guess is that as Qt needs less time to repaint a single plot even though its maximized( Maybe due to less pixel level changes).

So my question is, how can I optimize or enhance my code so that when I view all the plots together in the grid view, the plot is updated properly. How can I reduce the repaint time? Or is there a better solution?

UPDATE

I have profiled my code and you can view it at this pastebin page.

I tried "disableAutoRange". But still its not satisfactory.

kiran
  • 525
  • 1
  • 9
  • 26
  • 1
    First step is to profile your code. See http://stackoverflow.com/questions/17103698/plotting-large-arrays-in-pyqtgraph/17108463#17108463 – Luke Feb 07 '15 at 10:44
  • @Luke. Right now we are calling setData on each plot in a loop. I think this will trigger the repaint one by one. Can I disable this "per-plot" repaint and then,after calling setData for all plots, manually trigger the repaint on the widget which encapsulates the subplots?Maybe this will reduce the repainting time. – kiran Feb 09 '15 at 10:43
  • No, Qt will take care of limiting the effort it spends repainting. Don't try to guess, just profile your code :) – Luke Feb 09 '15 at 16:51
  • @Luke. Already profiled. Can you please check http://pastebin.com/KPbPkPwr and let me know if you have any suggestions – kiran Feb 10 '15 at 05:01
  • Sorry, I missed the update. I don't see an obvious opportunity to optimize, but a call graph might be more helpful in this case (eg http://stackoverflow.com/questions/4544784/how-can-you-get-the-call-tree-with-python-profilers). I also might be able to offer more advice if you post a working example (use random data). – Luke Feb 11 '15 at 11:26

0 Answers0