Множественное обновление графика с pyqtgraph в Python

Мне нужно построить 3 кривые обновления данных, которые я считываю с датчика. График обновления выполняется очень быстро, когда я использую только кривую, но когда я пытаюсь построить их все, каждый из них значительно медленнее. Код, который я использую, следующий:

#!/usr/bin/python


from pyqtgraph.Qt import QtGui, QtCore
import pyqtgraph as pg

import time
import numpy as np


app = QtGui.QApplication([])



win = pg.GraphicsWindow()

p1 = win.addPlot()
p2 = win.addPlot()
p3 = win.addPlot()


curve1 = p1.plot()

curve2 = p2.plot()

curve3 = p3.plot()

readData = [0.0, 0.0, 0.0]
y1=[0.0]
y2=[0.0]
y3=[0.0]

temp = [0.0]

start = time.time()

def update():
    global curve1, curve2, curve3
    t = time.time()-start         # measure of time as x-coordinate
    readData= readfun()        #function that reads data from the sensor it returns a list of 3 elements as the y-coordinates for the updating plots
    y1.append(readData[0])
    y2.append(readData[1])
    y3.append(readData[2])
    temp.append(t)

    curve1.setData(temp,y1)
    curve2.setData(temp,y2)
    curve3.setData(temp,y3)
    app.processEvents()



timer = QtCore.QTimer()
timer.timeout.connect(update)
timer.start(0)




if __name__ == '__main__':
    import sys
    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_'):
        QtGui.QApplication.instance().exec_()

Как я могу ускорить обновление графика для трех кривых? Спасибо

EDIT: Вдохновленный решением dirkjot, я хочу отредактировать приведенный выше код на случай, если он понадобится кому-то для той же цели. Он отлично работает:

#!/usr/bin/python


from pyqtgraph.Qt import QtGui, QtCore
import pyqtgraph as pg

import time
import numpy as np


app = QtGui.QApplication([])

win = pg.GraphicsWindow()

p1 = win.addPlot()
p2 = win.addPlot()
p3 = win.addPlot()


curve1 = p1.plot()

curve2 = p2.plot()

curve3 = p3.plot()

readData = [0.0, 0.0, 0.0]
y1=np.zeros(1000,dtype=float)
y2=np.zeros(1000,dtype=float)
y3=np.zeros(1000,dtype=float)

indx = 0
def update():
    global curve1, curve2, curve3, indx, y1,y2,y3

    readData= readfun()        #function that reads data from the sensor it returns a list of 3 elements as the y-coordinates for the updating plots
    y1[indx]=readData[0]
    y2[indx]=readData[1]
    y3[indx]=readData[2]

    if indx==99:
       y1=np.zeros(1000,dtype=float)
       y2=np.zeros(1000,dtype=float)
       y3=np.zeros(1000,dtype=float)
    else:
       indx+=1
    curve1.setData(y1)
    curve2.setData(y2)
    curve3.setData(y3)
    app.processEvents()



timer = QtCore.QTimer()
timer.timeout.connect(update)
timer.start(0)




if __name__ == '__main__':
    import sys
    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_'):
        QtGui.QApplication.instance().exec_()

person cyberdyne    schedule 18.11.2014    source источник


Ответы (1)


Одна проблема заключается в том, что вы добавляете к спискам. Это становится очень медленным, когда списки становятся большими, так как Python должен скопировать полный список в новое место, которое на одну ячейку больше, чем предыдущее. Вы можете проверить это, снова запустив свой код с удаленными добавлениями, но продолжая читать данные (которые вы отбрасываете для этого теста).

Если это проблема, есть несколько решений:

  1. предварительно выделите большой список (скажем, [None] * 1000) и держите счетчик там, где вы пишете. Оберните вокруг, когда вы достигнете 1k. Таким образом, вы получаете постоянно обновляемый дисплей, как на старомодном прицеле.
  2. Используйте numpy и предварительно выделите фиксированный буфер, скажем, 1k сэмплов. Добавьте образцы в конец (позиция от -10 до -1). Когда вы достигнете -1, переместите содержимое буфера 10 влево в эффективном операторе данных numpy (что-то вроде buffer[0:-10] = buffer[10:], но может быть специальная инструкция сдвига numpy) и снова начните запись с -10.
person dirkjot    schedule 19.12.2014