在python中滚动数组

时间:2018-11-14 15:44:23

标签: python numpy pyqt5 pyserial pyqtgraph

我目前正在用pyserial和pyqtgraph编写python脚本,以绘制通过串口从加速度计输入的数据。我将此数据附加到一个int数组,并使用它来更新绘图。目前,我的图形宽度为500(我仅显示最近的500个元素),并且通过在末尾附加元素并从头开始弹出来“滚动”或“滚动”。

data1 = [0] * 500

def update():
  global curve1, data1, x, ser
  if(ser != None): ## serial object. defined via a QPushButton event
    line = ser.readline()
    csv = line.decode().split(',')
    if len(csv) == 2:       
      data1.append(int(csv[1]))
      data1.pop(0)
      xdata1 = np.array(data1[-500:], dtype='int')
      curve1.setData(xdata1)
      x += 1
      curve1.setPos(x, 0)
      app.processEvents()

QtTimer对象调用此更新方法以更新绘图窗口

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

这样,我避免了数组不断增长,也避免了通过向左移动元素来复制值。但是,我的绘图不一致,并且有时会滞后(当我移动传感器时,绘图会在几秒钟后做出反应)。这是由于我无法有效地滚动数据吗?

2 个答案:

答案 0 :(得分:3)

要执行O(1)更新过程,您可以自己使用双数组缓冲区:

size=4
buffersize=2*size
buffer=np.zeros(buffersize+1,int) # one more room  for keep trace on beginning of buffer.
sensor=iter(range(1,10**5)) # emulation

def update():
    i=buffer[buffersize] # to avoid global variable i
    buffer[i]=buffer[i+size]=next(sensor) # double copy.
    buffer[buffersize]=i=(i+1)%size
    print(i,buffer[:buffersize],buffer[i:i+size])
    # In real life : curve1.SetData(buffer[i:i+size])

由于buffer[i:i+size]只是一个视图,因此无需花费任何时间来更新curve1

运行:

>>> for k in range(6): update()

1 [1 0 0 0 1 0 0 0] [0 0 0 1]
2 [1 2 0 0 1 2 0 0] [0 0 1 2]
3 [1 2 3 0 1 2 3 0] [0 1 2 3]
0 [1 2 3 4 1 2 3 4] [1 2 3 4]
1 [5 2 3 4 5 2 3 4] [2 3 4 5]
2 [5 6 3 4 5 6 3 4] [3 4 5 6]
....

答案 1 :(得分:0)

以下是这种FIFO功能的很好参考:Queues in Python

通过该链接进行总结:

请考虑使用collections.deque进行此操作,因为列表很慢。