PyQwt
对Qt
平台中的C++
绘图扩展库Qwt
进行包装,而guiqwt
又对PyQwt
进行了封装,使它更容易使用。与Python
最著名的绘图库matplotlib
相比,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()
请自行体会~_~
- 在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()
将绘图控件添加进管理列表。
❹添加标准的交互工具,并使其成为当前工具。在绘图控件中,按住鼠标中键拖动可以对图表的显示范围进行平移,按住鼠标右键拖动可以进行缩放。
❺通过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为键的字典。