2

I'm writing an application in PyQt that takes in 8 sensor waveforms and I have 8 QGraphicViews in one window that stream the 8 data. When I only use one sensor, everything works fine. But if I use all 8 real-time stream, the plotting becomes slowed and crashes.

What's the best practice and what one should be aware of when plotting lots of real-time streams at the same time to cut down on the performance time? Would multi-threading help? Plotting at slower framerate?

Alvin C
  • 127
  • 1
  • 11
  • How about downsampling? Have you considered downsampling your data (can be done externally, or using the downsample keyword and method). This would reduce the amount of data visible, since each graph should be smaller. I might also try lowering the sampling rate. Multithreading would be of little use, since you're still restricted to one core and the task is CPU-bound. http://www.pyqtgraph.org/documentation/graphicsItems/plotdataitem.html#pyqtgraph.PlotDataItem.__init__ – Alex Huszagh Apr 23 '16 at 22:00
  • Want me to write in an answer? I wasn't sure if that would be sufficient for you (kinda more so guidelines). Glad to hear it helps. – Alex Huszagh May 03 '16 at 22:23
  • Sure! Didn't realize PlotDataItem has a downsample option. thanks!! – Alvin C May 03 '16 at 22:25

1 Answers1

1

Since the task is CPU bound, and you're still running on one core (for Python, by default), multi-threading would be of little use. Furthermore, PyQtGraph cannot have any plotting done in multiple threads: everything must be done in the main thread (see the author's response to a similar subject here). So, although multi-threading or multiprocessing could help you with fetching or processing data, it will not fix the main bottleneck: the plotting of too much data in too little space at too high a rate.

The solution? Downsample. Conveniently, PyQtGraph has this builtin. Here is an example (modified from the PyQtGraph example suite).

import numpy as np
import pyqtgraph as pg
from PySide import QtGui, QtCore

win = pg.GraphicsWindow(title="Basic plotting examples")
win.resize(1000,600)
win.setWindowTitle('pyqtgraph example: Plotting')

# Enable antialiasing for prettier plots
pg.setConfigOptions(antialias=True)

p1 = win.addPlot(title="Downsampled")
# normally would plot 1000, but we downsample by 10 fold
p1.plot(np.random.normal(size=1000), pen=(255,0,0), name="Red curve", downsample=10)

p2 = win.addPlot(title="Normal")
p2.plot(np.random.normal(size=1000), pen=(0,0,255), name="Blue curve",)


## Start Qt event loop unless running in interactive mode or using pyside.
if __name__ == '__main__':
    QtGui.QApplication.instance().exec_()

And the result, here we have 10x less points on the left, allowing much higher performance.

Left, downsamples, right, Normal

Community
  • 1
  • 1
Alex Huszagh
  • 13,272
  • 3
  • 39
  • 67