1、问题描述
最近在使用pyqt5和pyqtgraph做界面,主要功能为:根据实时收集到的数据绘制折线图。我采用的方案为pyqtgraph的example的Scrolling Plots实现滚动画图,示例为下图二行二列位置。
一开始刚运行的时候,显示良好,但是当时间久了问题就出现了:由于窗口大小固定,随着时间的推移,数据量越来越多,折线之间的距离越来越近,会变得十分稠密,影响显示效果和使用者的体验。
我的设想为:当数据量较少时(刚开始运行不久),正常绘制更新。而当数据量较大的时候,图形照常绘制,但是横轴坐标随着数据更新而平移,每次只在整个窗口显示50个点所绘制的折线图,保持线与线之间的合理距离,从而不影响使用者感官。
2、解决办法
既然思想已经确定,那就开始干吧。具体代码如下:
def __init__(self, qSystem):
# self.guiplot_consensus为UI界面中的GraphicsLayoutWidget,是在qtdesigner中布局设置好的,此处不做赘述。
self.p1 = self.guiplot_consensus.addPlot(title="Consensus Time", row=1, col=0)
self.p2 = self.guiplot_growthRate.addPlot(title="Growth Rate", row=1, col=0)
# 初始化折线图形对象
self.curve_conTime = self.p1.plot(pen=(0, 255, 0))
self.curve_growth = self.p2.plot(pen=(0, 255, 0))
def child_plotSystem(self, consensusLatency, growth_rate, list_time):
# consensusLatency, growth_rate, list_time为画图需要的数据,list_time为横轴点的坐标集
if consensusLatency:
# 当数据点过于密集(len(list_time) > 50)时,图像开始滚动
if len(list_time) < 50:
self.curve_conTime.setData(list_time, consensusLatency)
self.curve_growth.setData(list_time, growth_rate)
else:
self.curve_conTime.setData(list_time, consensusLatency)
# 设置显示的横轴区域,从而实现滚动功能
self.p1.setXRange(list_time[-51], list_time[-1])
self.curve_growth.setData(list_time, growth_rate)
self.p2.setXRange(list_time[-51], list_time[-1])
上面代码中的函数child_plotSystem
可以理解为,每次收到数据的update函数。一旦收到新的数据,就会触发一次。滚动功能的实现关键为该函数的else中的setXRange()
,它用来设置显示的X轴区域,当要绘制的点的个数大于等于50的时候,折线图开始滚动,只显示最后51个点的图像,但是其它前面的点的图像也会画出来,鼠标点击并按住图像所在区域右拉即可看到。
最终效果如下图(已滚动显示一段距离):
3、pyqt5开发过程关键问题总结
若有问题,欢迎评论讨论学习~