用 guiqwt制作实时波形绘图程序
作者 : RY 标签: pyqt guiqwt
guiqwt是 Spyder的作者为其开发的一套基于 PyQwt的绘图扩展库。它能很方便地在 PyQt4
的界面程序中添加高效的绘图控件。本文介绍如何使用 guiqwt编写实时绘图程序。
guiqwt的 pyplot API
PyQwt对 Qt平台中的 C++绘图扩展库 Qwt进行包装,而 guiqwt又对 PyQwt进
行了封装,使它更容易使用。与 Python最著名的绘图库 matplotlib相比,guiqwt
的绘图功能虽然比较有限,然而它最大的优势在于其高效的绘图速度。因此我们
可以很方便地使用 guiqwt制作出对绘图实时性要求较高的程序。
http://packages.python.org/guiqwt/
guiqwt项目地址
在 guiqwt 中甚至还提供了一套与 pyplot 类似的 API,方便快速绘图,下面是一
个例子:
import numpy as np
from guiqwt.pyplot import *
t = np.linspace(0, 20, 1000)
u = np.sin(t) + np.random.randn(1000)
i = np.cos(t) + np.random.randn(1000)
subplot(2,1,1)
plot(t, u, "r-", label=u"电压")
xlabel(u"时间(秒)")
ylabel(u"电压(伏特)")
legend()
subplot(2,1,2)
plot(t, i, "g-", label=u"电流")
xlabel(u"时间(秒)")
ylabel(u"电流(安培)")
legend()
title(u"电压-电流")
show()
程序中用到了 subplot()、plot()、xlabel()、ylabel()、legend()、title()、show()等函
数,它们的用法与 matplotlib.pyplot中的同名函数类似。下面是程序的运行界面,
由界面截图可知,虽然曲线没有 matplotlib的精美,但是它提供了更多的工具按
钮和绘图配置功能:
在 PyQt4界面中插入绘图控件
qwtgui最大的用处还是在 PyQt4制作的界面程序中使用绘图控件。
import numpy as np
from PyQt4.QtGui import *
from PyQt4.QtCore import Qt
from guiqwt.plot import PlotManager, CurvePlot
from guiqwt.builder import make
class PlotDemo(QWidget):
def __init__(self):
super(PlotDemo, self).__init__()
self.setWindowTitle(u"Plot Demo")
self.manager = PlotManager(self) ❶
self.plot = CurvePlot() ❷
self.manager.add_plot(self.plot) ❸
self.manager.register_standard_tools() ❹
self.manager.get_default_tool().activate() ❹
t = np.arange(0, 20, 0.05)
x = np.sin(t) + np.random.randn(len(t))
curve = make.curve(t, x, color="red", title=u"正弦波") ❺
self.plot.add_item(curve) ❻
vbox = QVBoxLayout()
vbox.addWidget(self.plot)
self.setLayout(vbox)
要生成一个可交互的曲线图控件,需要三个对象:PlotManager、CurvePlot、
CurveItem。其中 CurvePlot 是曲线图控件;CurveItem 是控件中所显示的曲线,
它管理曲线 X-Y轴的数据;而 PlotManager则可以用来管理一个或者多个绘图控
件,为其添加各种交互功能。
❶创建 PlotManager对象,❷创建 CurvePlot对象,并❸调用 PlotManager对象
的 add_plot()将绘图控件添加进管理列表。
❹添加
标准
excel标准偏差excel标准偏差函数exl标准差函数国标检验抽样标准表免费下载红头文件格式标准下载
的交互工具,并使其成为当前工具。在绘图控件中,按住鼠标中键
拖动可以对图表的显示范围进行平移,按住鼠标右键拖动可以进行缩放。
❺通过 make模块中的 curve()创建一个 CurveItem对象,它的颜色为红色,标题
为 u”正弦波”。❻最后调用 CurvePlot 对象的 add_item()将曲线对象添加进绘图
对象的项目列表中。
程序的显示效果如下:
X轴范围同步
在实时的数据显示程序中,通常需要多个绘图控件的横轴(时间轴)的范围保持
一致,下面的程序实现这一功能:
class SyncXAxisDemo(QWidget):
def __init__(self):
super(SyncXAxisDemo, self).__init__()
self.setWindowTitle(u"Plot Demo")
t = np.arange(0, 20, 0.05)
sin1f = np.sin(t)
sin3f = 1/6.0*np.sin(3*t)
vbox = QVBoxLayout()
self.manager = PlotManager(self)
for i, data in enumerate([sin1f, sin3f, sin1f+sin3f]):
plot = CurvePlot()
plot.axisScaleDraw(CurvePlot.Y_LEFT).setMinimumExtent(60) ❶
plot.plot_id = id(plot) ❷
curve = make.curve(t, data, color="blue")
plot.add_item(curve)
vbox.addWidget(plot)
self.manager.register_standard_tools()
self.manager.get_default_tool().activate()
self.manager.synchronize_axis(CurvePlot.X_BOTTOM,
self.manager.plots.keys()) ❸
self.setLayout(vbox)
程序中,我们用 QVBoxLayout 将多个 CurvePlot 控件垂直排列。❶为了让图表
的左边框垂直对齐,通过 setMinimumExtent()设置 Y轴刻度区域的最小宽度,请
读者根据多个图表中最大的 Y轴刻度区域调整其参数。❷在 qwtgui 2.1.6中存在
一个 BUG,使得我们必须在调用 manager.add_plot()之后设置被添加的 plot控件
的 plot_id属性为 id(plot)。❸调用 PlotManager的 synchronize_axis(),让其所管
理的所有绘图控件的 X轴始终保持一致。synchronize_axis()的第一个参数指定所
同步的轴,而第二个参数指定需要同步的绘图控件的 id。而 PlotManager的 plots
属性是一个以绘图控件的 id为键的字典。
下面是程序的界面截图:
实时波形绘图程序
下面是实时波形绘图程序的界面截图:
在每个绘图控件中都有两条曲线。通过上方的工具条可以控制绘图控件的 X 轴
和 Y轴的显示范围。显示范围分为自动和手动,共有三种情况:
1. 当不勾选“X轴自动调节”时,图表的显示范围可由用户用鼠标改变。
2. 当勾选“X轴自动调节”,不勾选“Y轴自动调节”时,图表的 Y轴显示范围
可由鼠标改变,而X轴则显示最新N秒的数据,N由工具条中的数字决定。
3. 当同时勾选“X轴自动调节”、“Y轴自动调节”时,X轴显示最新 N秒的数
据,而 Y轴自动根据这 N秒的数据的范围修改。
程序中使用 array 模块的动态数组实现数据收集,关于这方面的
内容
财务内部控制制度的内容财务内部控制制度的内容人员招聘与配置的内容项目成本控制的内容消防安全演练内容
请读者参
考: 在 NumPy中使用动态数组 。
程序中还使用了 通过降低采样点数快速绘制曲线 中介绍的方法实现绘图控件的
快速响应。
http://hyry.dip.jp/tech/code/code/8
实时波形绘图程序的源代码
为了演示实时的效果,程序中采用定时器产生新的数据。而在实际的系统中,数据可能通过
串口、AD设备、socket通信等方式获得,由于获得数据所需的等待时间可能较长,因此为
了不影响界面的响应,通常需要使用线程或 gevent 中的协程实现数据采集。