Signals 希望使用Vispy场景画布显示两个实时信号

Signals 希望使用Vispy场景画布显示两个实时信号,signals,real-time,pyserial,vispy,Signals,Real Time,Pyserial,Vispy,我正在尝试使用Vispy实时采集和显示信号。我通过pyserial通过串口获取信号 我已经修改了realtime_signals示例(),并且能够单独显示每个信号。我还可以显示相同信号的3或5个绘图。但我无法在同一画布或插入PyQt5应用程序的两个不同画布中显示两个信号(每个信号来自不同的串行端口)。我没有OpenGL和着色器的经验 串行端口代码和修改后的场景计时器代码如下所示 #导入多处理 从PyQt5.QtWidgets导入* 导入vispy.app 导入系统 来自vispy进口gloo 从

我正在尝试使用Vispy实时采集和显示信号。我通过pyserial通过串口获取信号

我已经修改了realtime_signals示例(),并且能够单独显示每个信号。我还可以显示相同信号的3或5个绘图。但我无法在同一画布或插入PyQt5应用程序的两个不同画布中显示两个信号(每个信号来自不同的串行端口)。我没有OpenGL和着色器的经验

串行端口代码和修改后的场景计时器代码如下所示

#导入多处理
从PyQt5.QtWidgets导入*
导入vispy.app
导入系统
来自vispy进口gloo
从vispy导入应用程序
将numpy作为np导入
输入数学
导入序列号
数据m=0.0
seri=serial.serial(“/dev/ttyACM0”,波特率=115200,超时=1)
类串行端口(串行。串行):
def oku():
全局数据
而seri.isOpen:
数据获取=“”
serialData=seri.read().decode('ascii')
如果serialData='$':
而不是serialData==';':
serialData=seri.read().decode('ascii')
如果不是serialData==';':
dataGet+=serialData
如果不是dataGet中的“$”:
dataList=dataGet.split(',')
如果len(数据列表)==3:
datam=float(dataList[0])-125000
打印(datam)
返回数据
#表中的列数和行数。
nrows=3
ncols=1
#信号数量.x=np.arange(样本)
m=nrows*ncols
#每个信号的采样数。
n=1000
#不同的信号幅度。
振幅=.1+.2*np.random.rand(m,1).aType(np.float32)
#将信号生成为(m,n)阵列。
#y=振幅*np.随机.随机数n(m,n).aType(np.float32)
y=np.zero([m,n],dtype=np.float32)
#每个顶点的颜色(TODO:使用基于GLSL的
#颜色映射和索引)。
颜色=np.重复(np.随机.均匀(大小=(m,3),低=.5,高=.9),
n、 axis=0).aType(np.32)
#信号每个顶点的2D索引(行和列)和x索引(样本索引
#在每个信号中)。
索引=np.c_uu[np.repeat(np.repeat)(np.arange(ncols),nrows),n),
np.重复(np.tile(np.arange(nrows),ncols),n),
np.tile(np.arange(n),m)].aType(np.32)
VERT_着色器=“”
#版本120
//位置的y坐标。
属性浮动一个_位置;
//行、列和时间索引。
属性向量3 a_指数;
可变vec3 v_指数;
//二维比例因子(缩放)。
均匀vec2u_标度;
//桌子的大小。
均匀的vec2u_大小;
//每个信号的采样数。
均匀浮动u_n;
//颜色。
属性向量3 a_颜色;
可变的vec4 v_颜色;
//用于在片段着色器中剪裁的各种变量。
可变vec2 v_位置;
可变vec4 v_ab;
void main(){
浮动nrows=u_size.x;
浮点数ncols=u_size.y;
//根据时间索引计算x坐标。
浮动x=-1+2*a_指数.z/(u_n-1);
vec2位置=vec2(x-(1-1/u_scale.x),a_位置);
//找到子地块的仿射变换。
vec2 a=vec2(1./ncols,1./nrows)*.9;
vec2b=vec2(-1+2*(a_index.x+.5)/ncols,
-1+2*(a_指数y+.5)/nrows);
//应用静态子批次转换+缩放。
gl_位置=vec4(a*u_刻度*位置+b,0.0,1.0);
v_color=vec4(a_color,1.);
v_指数=a_指数;
//用于片段着色器中的剪裁测试。
v_位置=gl_位置.xy;
v_ab=vec4(a,b);
}
"""
FRAG_着色器=“”
#版本120
可变的vec4 v_颜色;
可变vec3 v_指数;
可变vec2 v_位置;
可变vec4 v_ab;
void main(){
gl_FragColor=v_颜色;
//丢弃信号之间的片段(模拟GLMultiDrawArray)。
如果((分形(v_index.x)>0。)(分形(v_index.y)>0。))
丢弃;
//剪切试验。
vec2试验=abs((v_位置xy-v_ab.zw)/v_ab.xy);
如果((测试x>1)| |(测试y>1))
丢弃;
}
"""
类画布(app.Canvas):
定义初始化(自):
app.Canvas.\uuuu init\uuuuu(self,title='Use your wheel to zoom!',
按键(交互式)
self.program=gloo.program(垂直着色器、框架着色器)
self.program['a_position']=y.reformate(-1,1)
self.program['a_color']=color
self.program['a_index']=index
self.program['u_scale']=(1,1.)
self.program['u_size']=(nrows,ncols)
self.program['u_n']=n
gloo.set_视口(0,0,*self.physical_大小)
self.\u timer=app.timer(0.001,connect=self.on\u timer,start=True)
gloo.set_状态(清除颜色=黑色),混合=真,
blend_func=('src_alpha','1减去'src_alpha'))
self.show()
def on_resize(自我,事件):
gloo.set_视口(0,0,*事件。物理_大小)
鼠标滚轮上的def(自身,事件):
dx=np.符号(事件增量[1])*.05
scale_x,scale_y=self.program['u_scale']
scale_x_new,scale_y_new=(scale_x*math.exp(2.5*dx),
比例y*math.exp(0.0*dx))
self.program['u_scale']=(max(1,scale_x_新)、max(1,scale_y_新))
self.update()
def on_定时器(自身、事件):
“”“在每个信号的末尾添加一些数据(实时信号)。”“”
全局数据
k=1
y[:,:-k]=y[:,k:]
#y[:,-k:]=datam/50000
y[:,-k:]=(Seriport.oku()/5000)
#y[:,-k:]=振幅*np.random.randn(m,k)
self.program['a_position'].set_数据(y.ravel().astype(np.float32))
self.update()
def on_draw(自身、事件):
gloo.clear()
self.program.draw('line\u strip')
canvas=canvas()
w=QMainWindow()
widget=QWidget()
frame=QFrame()
w、 setCentralWidget(小部件)
setLayout(QHBoxLayout())
frame.setLayout(QVBoxLayout())
widget.layout().addWidget(canvas.native)
#widget.layout().addWidget(canvas2.native)
widget.layout().addWid