在 python 中滚动数组
Scrolling an array in python
我目前正在用 pyserial 和 pyqtgraph 编写一个 python 脚本,用于绘制通过串行端口从加速度计传入的数据。我将此数据附加到一个 int 数组并使用它来更新绘图。目前,我的图表宽度是 500(我只显示最近的 500 个元素),我 "roll" 或 "scroll" 通过将一个元素附加到末尾并从开头弹出。
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 对象调用此更新方法来更新绘图window
timer = QtCore.QTimer()
timer.timeout.connect(update)
timer.start(0)
这样我就避免了不断增长的数组,也避免了通过向左移动元素来复制值。然而,我的情节不一致并且偶尔会滞后(当我移动传感器时,情节会在几秒钟后做出反应)。这是因为我滚动数据效率低下吗?
下面是此类 FIFO 功能的一个很好的参考:Queues in Python
总结link:
考虑对这种行为使用 collections.deque
,因为列表很慢。
要有一个 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]
....
我目前正在用 pyserial 和 pyqtgraph 编写一个 python 脚本,用于绘制通过串行端口从加速度计传入的数据。我将此数据附加到一个 int 数组并使用它来更新绘图。目前,我的图表宽度是 500(我只显示最近的 500 个元素),我 "roll" 或 "scroll" 通过将一个元素附加到末尾并从开头弹出。
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 对象调用此更新方法来更新绘图window
timer = QtCore.QTimer()
timer.timeout.connect(update)
timer.start(0)
这样我就避免了不断增长的数组,也避免了通过向左移动元素来复制值。然而,我的情节不一致并且偶尔会滞后(当我移动传感器时,情节会在几秒钟后做出反应)。这是因为我滚动数据效率低下吗?
下面是此类 FIFO 功能的一个很好的参考:Queues in Python
总结link:
考虑对这种行为使用 collections.deque
,因为列表很慢。
要有一个 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]
....