我按照这个使用 Vispy 线程将标签添加到实时信号绘图并尝试使用来自https://vispy.org/gallery/scene/line_update.html#sphx-glr-gallery-scene-line-update-py的示例。我如何保存绘制的信息,我应该能够通过平移视图来查看过去的数据。我应该将绘制的数据存储在其他地方并检索它以查看旧数据吗?随着新数据添加到视图中,我试图保留所有信息。关于如何做到这一点的任何建议都会非常有帮助。
谢谢。
更新 1:
'''
import sys
import numpy as np
from vispy import app, scene
# vertex positions of data to draw
N = 100
pos = np.zeros((N, 2), dtype=np.float32)
x_lim = [0, 10.]
y_lim = [-2., 2.]
pos[:, 0] = np.linspace(x_lim[0], x_lim[1], N)
pos[:, 1] = np.random.normal(size=N)
# color array
color = np.ones((N, 4), dtype=np.float32)
color[:, 0] = np.linspace(0, 1, N)
color[:, 1] = color[::-1, 0]
canvas = scene.SceneCanvas(keys='interactive', show=True)
grid = canvas.central_widget.add_grid(spacing=0)
viewbox = grid.add_view(row=0, col=1, camera='panzoom')
# add some axes
x_axis = scene.AxisWidget(orientation='bottom')
x_axis.stretch = (1, 0.1)
grid.add_widget(x_axis, row=1, col=1)
x_axis.link_view(viewbox)
y_axis = scene.AxisWidget(orientation='left')
y_axis.stretch = (0.1, 1)
grid.add_widget(y_axis, row=0, col=0)
y_axis.link_view(viewbox)
# add a line plot inside the viewbox
line = scene.Line(pos, color, parent=viewbox.scene)
# auto-scale to see the whole line.
viewbox.camera.set_range()
import time
t0 = time.time()
x_val = []
y_val= []
def update(ev):
'''
New x and y coordinates are generated and assigned to `pos`.
`datastore` variable holds all the data (past and current
generated data). Only `pos` data is used to update the plot in
real time.
'''
global pos, color, line, x_val, y_val,datastore
pos[:, 0] = np.linspace(x_lim[0], x_lim[1], N)+time.time()-t0
pos[:, 1] = np.sin(pos[:, 0])+0.2*np.random.normal(size=(N))
x_val= np.append(x_val,pos[:,0])
y_val= np.append(y_val,pos[:,1])
datastore=np.stack((x_val, y_val),axis=1)
# print(pos.size)
color = np.roll(color, 1, axis=0)
line.set_data(pos=pos)
viewbox.camera.set_range(y=(pos[:, 1].max(), pos[:, 1].min()), x=(pos[:, 0].max(), pos[:, 0].min()))
def mouseMove(ev):
'''
`datastore` consists of all data. Based on the camera view,
data is extracted from `datastore`. this extracted data is
used to update the plot.
'''
print(viewbox.camera.get_state()['rect'])
currentBounds= viewbox.camera.get_state()['rect']
currentMin_x = currentBounds.right
currentMax_x = currentBounds.left
if currentMin_x < datastore[:,0].min():
currentMin_x = datastore[:,0].min()
if currentMax_x > datastore[:,0].max():
currentMax_x = datastore[:,0].max()
getData = datastore[(datastore[:,0]> currentMin_x) & (datastore[:,0]< currentMax_x)][:100] #Should be equal to N, for code to work
print(getData.size)
line.set_data(pos=getData, color=color) #Updates plot with the extracted data
viewbox.camera.set_range(y=(getData[:, 1].max(), getData[:, 1].min()), x=(getData[:, 0].max(), getData[:, 0].min()))
print(viewbox.camera.get_state())
t = app.Timer()
t.connect(update)
t.start(iterations=60*5)
viewbox.events.mouse_release.connect(mouseMove)
t.events.stop.connect(lambda x: app.quit())
if __name__ == '__main__' and sys.flags.interactive == 0:
app.run()
'''
Update 2
import sys
import numpy as np
from vispy import app, scene
# vertex positions of data to draw
N = 100
pos = np.zeros((N, 2), dtype=np.float32)
x_lim = [0, 10.]
y_lim = [-2., 2.]
pos[:, 0] = np.linspace(x_lim[0], x_lim[1], N)
pos[:, 1] = np.random.normal(size=N)
canvas = scene.SceneCanvas(keys='interactive', show=True)
grid = canvas.central_widget.add_grid(spacing=0)
viewbox = grid.add_view(row=0, col=1, camera='panzoom')
# add some axes
x_axis = scene.AxisWidget(orientation='bottom')
x_axis.stretch = (1, 0.1)
grid.add_widget(x_axis, row=1, col=1)
x_axis.link_view(viewbox)
y_axis = scene.AxisWidget(orientation='left')
y_axis.stretch = (0.1, 1)
grid.add_widget(y_axis, row=0, col=0)
y_axis.link_view(viewbox)
# add a line plot inside the viewbox
line = scene.Line(pos, parent=viewbox.scene)
# auto-scale to see the whole line.
viewbox.camera.set_range()
import time
t0 = time.time()
x_val = []
y_val= []
def update(ev):
global pos, line, x_val, y_val,datastore
pos[:, 0] = np.linspace(x_lim[0], x_lim[1], N)+time.time()-t0
pos[:, 1] = np.sin(pos[:, 0])+0.2*np.random.normal(size=(N))
x_val= np.append(x_val,pos[:,0])
y_val= np.append(y_val,pos[:,1])
datastore=np.stack((x_val, y_val),axis=1)
# print(pos.size)
line.set_data(pos=pos)
viewbox.camera.set_range(x=(pos[:, 0].min(),pos[:, 0].max()),y=(pos[:, 1].min(),pos[:, 1].max()))
def mouseMove(ev):
print(viewbox.camera.get_state()['rect'])
currentBounds= viewbox.camera.get_state()['rect']
currentMin_x = currentBounds.left
currentMax_x = currentBounds.right
print(currentMin_x, currentMax_x)
getData = datastore[(datastore[:,0]>currentMin_x) & (datastore[:,0]< currentMax_x)] #Should be equal to N, for code to work
print(getData)
print(getData.size)
line.set_data(pos=getData)
viewbox.camera.set_range( x=( getData[:, 0].min(),getData[:, 0].max()),y=(getData[:, 1].min(),getData[:, 1].max()))
print(viewbox.camera.get_state())
t = app.Timer()
t.connect(update)
t.start(iterations=60*15)
viewbox.events.mouse_release.connect(mouseMove)
t.events.stop.connect(lambda x: app.quit())
if __name__ == '__main__' and sys.flags.interactive == 0:
app.run()