Search code examples
pythonnumpypyqtgraph

How to I make a PyQtGraph scrolling graph clear the previous line within a loop


I wish to plot some data from an array with multiple columns, and would like each column to be a different line on the same scrolling graph. As there are many columns, I think it would make sense to plot them within a loop. I'd also like to plot a second scrolling graph with a single line.

I can get the single line graph to scroll correctly, but the graph containing the multiple lines over-plots from the updated array without clearing the previous lines.

How do I get the lines to clear within the for loop. I thought that setData, might do the clearing. Do I have to have a pg.QtGui.QApplication.processEvents() or something similar within the loop? I tried to add that call but had it no effect.

My code:

#Based on example from PyQtGraph documentation

import numpy as np
import pyqtgraph as pg

win = pg.GraphicsLayoutWidget(show=True)
win.setWindowTitle('pyqtgraph example: Scrolling Plots')
timer = pg.QtCore.QTimer()

plot_1 = win.addPlot()
plot_2 = win.addPlot()
data1 = np.random.normal(size=(300))
curve1 = plot_1.plot(data1)
data_2d = np.random.normal(size=(3,300))

def update_plot():
    global data1, data_2d
    data1[:-1] = data1[1:]  
    data1[-1] = np.random.normal()
    curve1.setData(data1)

    for idx, n in enumerate(data_2d):
        n[:-1] = n[1:]
        n[-1] = np.random.normal()
        curve2 = plot_2.plot(n,pen=(idx))
        curve2.setData(n)
        #pg.QtGui.QApplication.processEvents() #Does nothing


timer = pg.QtCore.QTimer()
timer.timeout.connect(update_plot)
timer.start(50)

if __name__ == '__main__':
    pg.exec()


Solution

  • You could clear the plot of all curves each time with .clear(), but that wouldn't be very performant. A better solution would be to keep all the curve objects around and call setData on them each time, like you're doing with the single-curve plot. E.g.

    curves_2d = [plot_2.plot(pen=idx) for idx, n in enumerate(data_2d)]
    
    # ... in update_plot
            curves_2d[idx].setData(n)