python 多轴和动图之pyqtgraph
2 年前
· 来自专栏
python数据分析
上篇讲了matplotlib进行多轴和动图的画图之外,这次来看看pyqtgraph如何画多轴和动图。pyqtgraph是Python中的一个库,可以和pyqt5控件来结合使用。它和matplotlib不同的是,它更倾向于绘制数据量比较大的情形,除此之外,绘制动图更新图的速度也要快些。
1、多轴
先来看看如何画多轴
import pyqtgraph as pg
app = pg.QtGui.QApplication([])
# 定义轴,想拥有几根轴就定义几个
a2 = pg.AxisItem("left")
a3 = pg.AxisItem("left")
a4 = pg.AxisItem("left")
a5 = pg.AxisItem("left")
a6 = pg.AxisItem("left")
# 视图框,用于存放折线
v2 = pg.ViewBox()
v3 = pg.ViewBox()
v4 = pg.ViewBox()
v5 = pg.ViewBox()
v6 = pg.ViewBox()
# 创建视图
pw = pg.GraphicsView()
pw.setWindowTitle('pyqtgraph 标题')
pw.show()
# 创建图形布局
l = pg.GraphicsLayout()
# 设置视图中心小部件 为该布局
pw.setCentralWidget(l)
# 向布局添加轴
# 注意这里col参数的位置,col的值大小表示轴的排列位置
l.addItem(a2, row = 2, col = 5, rowspan=1, colspan=1)
l.addItem(a3, row = 2, col = 4, rowspan=1, colspan=1)
l.addItem(a4, row = 2, col = 2, rowspan=1, colspan=1)
l.addItem(a5, row = 2, col = 3, rowspan=1, colspan=1)
l.addItem(a6, row = 2, col = 1, rowspan=1, colspan=1)
#l.addItem(a6, row = 2, col = 3, rowspan=1, colspan=1)
# 至少有一个绘图项使用它自己的视图框和左轴。
pI = pg.PlotItem() # 定义一个绘图项
v1 = pI.vb # 对绘图项的视图框的引用
l.addItem(pI, row = 2, col = 6, rowspan=1, colspan=1) # 添加绘图框到图形布局
# 向绘图框添加视图框
l.scene().addItem(v2)
l.scene().addItem(v3)
l.scene().addItem(v4)
l.scene().addItem(v5)
l.scene().addItem(v6)
# 用轴连接 存放折线的视图框
a2.linkToView(v2)
a3.linkToView(v3)
a4.linkToView(v4)
a5.linkToView(v5)
a6.linkToView(v6)
# 链接视图框,绘图项的视图框上,整体缩放所有的折线
v2.setXLink(v1)
v3.setXLink(v2)
v4.setXLink(v3)
v5.setXLink(v4)
v6.setXLink(v5)
# 轴标签
pI.getAxis("left").setLabel('axis 1 in ViewBox of PlotItem', color='#FFFFFF')
a2.setLabel('axis 2 in Viewbox 2', color='#2E2EFE')
a3.setLabel('axis 3 in Viewbox 3', color='#2EFEF7')
a4.setLabel('axis 4 in Viewbox 4', color='#2EFE2E')
a5.setLabel('axis 5 in Viewbox 5', color='#FFFF00')
a6.setLabel('axis 6 in Viewbox 6', color='#FE2E64')
# slot: 插槽:调整大小时更新视图
def updateViews():
# setGeometry设置几何图形
# sceneBoundingRect场景边界矩形
v2.setGeometry(v1.sceneBoundingRect())
v3.setGeometry(v1.sceneBoundingRect())
v4.setGeometry(v1.sceneBoundingRect())
v5.setGeometry(v1.sceneBoundingRect())
v6.setGeometry(v1.sceneBoundingRect())
# 折线点值 (轴刻度范围自动按最大最小值生成)
x = [1,2,3,4,5,6]
y1 = [0,4,6,8,10,4]
y2 = [0,5,7,9,11,3]
y3 = [0,1,2,3,4,12]
y4 = [0,8,0.3,0.4,2,5]
y5 = [0,1,6,4,2,1]
y6 = [0,0.2,0.3,0.4,0.5,0.6]
# 给绘图项的视图框添加折线xy点的值,折线颜色
v1.addItem(pg.PlotCurveItem(x, y1, pen='#FFFFFF'))
v2.addItem(pg.PlotCurveItem(x, y2, pen='#2E2EFE'))
v3.addItem(pg.PlotCurveItem(x, y3, pen='#2EFEF7'))
v4.addItem(pg.PlotCurveItem(x, y4, pen='#2EFE2E'))
v5.addItem(pg.PlotCurveItem(x, y5, pen='#FFFF00'))
v6.addItem(pg.PlotCurveItem(x, y6, pen='#FE2E64'))
# 调整大小时更新
v1.sigResized.connect(updateViews)
# 开始时自动调整一次以适应视图
# enableAutoRange 启用自动范围
v2.enableAutoRange(axis= pg.ViewBox.XYAxes, enable=True)
v3.enableAutoRange(axis= pg.ViewBox.XYAxes, enable=True)
v4.enableAutoRange(axis= pg.ViewBox.XYAxes, enable=True)
v5.enableAutoRange(axis= pg.ViewBox.XYAxes, enable=True)
v6.enableAutoRange(axis= pg.ViewBox.XYAxes, enable=True)
updateViews()
app.exec_()
最终效果
2、动图
import pyqtgraph as pg
import numpy as np
import array
app = pg.mkQApp()#建立app
win = pg.GraphicsWindow()#建立窗口
win.setWindowTitle(u'pyqtgraph逐点画波形图')
win.resize(800, 500)#小窗口大小
data =[] #可动态改变数组的大小,double型数组
historyLength = 100#横坐标长度
p = win.addPlot()#把图p加入到窗口中
idx = 0
p.showGrid(x=True, y=True)#把X和Y的表格打开
p.setLabel(axis='left', text='y / V')#靠左
p.setLabel(axis='bottom', text='x / point')
p.setTitle('y = sin(x)')#表格的名字
curve = p.plot()#绘制一个图形
def plotData():
global idx#内部作用域想改变外部域变量
global B
tmp = np.sin(np.pi / 50 * idx)
if len(data)<historyLength:
#print(len(data))
data.append(tmp)
#print(B)
p.setRange(xRange=[0, historyLength+0], yRange=[-1.2, 1.2], update=False)
#print(data)
else:
data.append(tmp)
B=B+1
# print(B)
p.setRange(xRange=[B, historyLength+B], yRange=[-1.2, 1.2], update=False)
#data[:-1] = data[1:]#前移
#data[-1] = tmp
if B>100:
timer.stop()
curve.setData(data)
idx += 1
timer = pg.QtCore.QTimer()
timer.timeout.connect(plotData)#定时调用plotData函数
timer.start(50)#多少ms调用一次
app.exec_()
最终效果
3、多轴和动图
如何画一张图,既是多轴又是动图呢
import pyqtgraph as pg
import numpy as np
app = pg.QtGui.QApplication([])
# 定义轴
a2 = pg.AxisItem("left")
a3 = pg.AxisItem("left")
a4 = pg.AxisItem("left")
a5 = pg.AxisItem("left")
a6 = pg.AxisItem("left")
# 视图框,用于存放折线
v2 = pg.ViewBox()
v3 = pg.ViewBox()
v4 = pg.ViewBox()
v5 = pg.ViewBox()
v6 = pg.ViewBox()
# 创建视图
pw = pg.PlotWidget()
pw.setWindowTitle('pyqtgraph 标题')
pw.show()
# 创建图形布局
l = pg.GraphicsLayout()
# 设置视图中心小部件 为该布局
pw.setCentralWidget(l)
# 向布局添加轴
# 注意这里col参数的位置
l.addItem(a2, row = 2, col = 5, rowspan=1, colspan=1)
l.addItem(a3, row = 2, col = 4, rowspan=1, colspan=1)
l.addItem(a4, row = 2, col = 3, rowspan=1, colspan=1)
l.addItem(a5, row = 2, col = 2, rowspan=1, colspan=1)
l.addItem(a6, row = 2, col = 1, rowspan=1, colspan=1)
#l.addItem(a6, row = 2, col = 3, rowspan=1, colspan=1)
# 至少有一个绘图项使用它自己的视图框和左轴。
pI = pg.PlotItem() # 定义一个绘图项
v1 = pI.vb # 对绘图项的视图框的引用
l.addItem(pI, row = 2, col = 6, rowspan=1, colspan=1) # 添加绘图框到图形布局
# 向绘图框添加视图框
l.scene().addItem(v2)
l.scene().addItem(v3)
l.scene().addItem(v4)
l.scene().addItem(v5)
l.scene().addItem(v6)
# 用轴连接 存放折线的视图框
a2.linkToView(v2)
a3.linkToView(v3)
a4.linkToView(v4)
a5.linkToView(v5)
a6.linkToView(v6)
# 链接视图框,我也不知道干嘛这样写,但是写上就会在--绘图项的视图框上,整体缩放所有的折线
v2.setXLink(v1)
v3.setXLink(v2)
v4.setXLink(v3)
v5.setXLink(v4)
v6.setXLink(v5)
# 轴标签
pI.getAxis("left").setLabel('axis 1 in ViewBox of PlotItem', color='#FFFFFF')
a2.setLabel('axis 2 in Viewbox 2', color='#2E2EFE')
a3.setLabel('axis 3 in Viewbox 3', color='#2EFEF7')
a4.setLabel('axis 4 in Viewbox 4', color='#2EFE2E')
a5.setLabel('axis 5 in Viewbox 5', color='#FFFF00')
a6.setLabel('axis 6 in Viewbox 6', color='#FE2E64')
historyLength = 100#横坐标长度
#p = win.addPlot()#把图p加入到窗口中
pI.showGrid(x=True, y=True)#把X和Y的表格打开
pI.setLabel(axis='bottom', text='x / point')
# slot: 插槽:调整大小时更新视图
def updateViews():
# setGeometry设置几何图形
# sceneBoundingRect场景边界矩形
v2.setGeometry(v1.sceneBoundingRect())
v3.setGeometry(v1.sceneBoundingRect())
v4.setGeometry(v1.sceneBoundingRect())
v5.setGeometry(v1.sceneBoundingRect())
v6.setGeometry(v1.sceneBoundingRect())
# 折线点值 (轴刻度范围自动按最大最小值生成)
x = []
y1 = []
y2 = []
y3 = []
y4 = []
y5 = []
y6 = []
def plotdata():
global i
global B
tmp = np.sin(np.pi / 50 * i)
x.append(i)
y1.append(tmp)
y2.append(1.5 * tmp)
y3.append(2 * tmp)
y4.append(2.5 * tmp)
y5.append(tmp * 3)
y6.append(tmp * 3.5)
# pI.setRange(xRange=[0, historyLength + 0], yRange=[-5, 20], update=True)
# 给绘图项的视图框添加折线xy点的值,折线颜色
v1.addItem(pg.PlotCurveItem(x, y1, pen='#FFFFFF'))
v2.addItem(pg.PlotCurveItem(x, y2, pen='#2E2EFE'))
v3.addItem(pg.PlotCurveItem(x, y3, pen='#2EFEF7'))
v4.addItem(pg.PlotCurveItem(x, y4, pen='#2EFE2E'))
v5.addItem(pg.PlotCurveItem(x, y5, pen='#FFFF00'))
v6.addItem(pg.PlotCurveItem(x, y6, pen='#FE2E64'))
if len(x) >=historyLength:
B = B + 1
else:
B = 0
# print(B)
pI.setRange(xRange=[B, historyLength + B], yRange=[-15, 20], update=True)
i=i+1
# 调整大小时更新
v1.sigResized.connect(updateViews)
# 开始时自动调整一次以适应视图
# enableAutoRange 启用自动范围
v2.enableAutoRange(axis= pg.ViewBox.XYAxes, enable=True)
v3.enableAutoRange(axis= pg.ViewBox.XYAxes, enable=True)
v4.enableAutoRange(axis= pg.ViewBox.XYAxes, enable=True)
v5.enableAutoRange(axis= pg.ViewBox.XYAxes, enable=True)
v6.enableAutoRange(axis= pg.ViewBox.XYAxes, enable=True)
timer = pg.QtCore.QTimer()