Skip to main content
 首页 » 编程设计

python之在python中滚动数组

2025年05月04日20zlslch

我目前正在使用 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) 

这样我就避免了不断增长的数组,也避免了通过向左移动元素来复制值。然而,我的情节不一致并且偶尔会滞后(当我移动传感器时,情节会在几秒钟后使用react)。这是因为我滚动数据效率低下吗?

请您参考如下方法:

要有一个 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] 只是一个 View ,因此更新 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] 
....