Python编程中一个超级强大的2D/3D绘图库——Pyqtgraph

pyqtgraph是Python平台上一种功能强大的2D/3D绘图库,相当于matplotlib库,比它更强大。因为内部实现方式上,使用了高速计算的numpy信号处理库以及Qt的GraphicsView框架。

Pyqtgraph的git地址和官网地址分别是:

https://github.com/pyqtgraph/pyqtgraph
http://pyqtgraph.org/

本文将简单介绍Pyqtgraph的安装及使用过程。

安装

安装pyqtgraph库的命令如下(可以用阿里的镜像):

pip install -i https://mirrors.aliyun.com/pypi/simple pyqtgraph

安装PyQt5库的命令如下(同样可以使用阿里的镜像):

pip install -i https://mirrors.aliyun.com/pypi/simple PyQt5
画图

我们利用pyqtgraph库来画sin函数和cos函数的曲线图,代码如下:

import pyqtgraph as pg
import numpy as np
import array

app = pg.mkQApp() # 建立app
win = pg.GraphicsWindow() # 建立窗口
win.setWindowTitle('pyqtgraph逐点画波形图') # 窗口名称
win.resize(800, 500) # 窗口大小

data = array.array('d') # 可动态改变数组的大小,double型数组
historyLength = 100 # 横坐标长度
p = win.addPlot() # 把图p加入到窗口中
p.showGrid(x=True, y=True) # 把X和Y的表格打开
p.setRange(xRange=[0, historyLength], yRange=[-1.2, 1.2], padding=0)
p.setLabel(axis='left', text='y / V') # 靠左,y轴
p.setLabel(axis='bottom', text='x / point') # 靠下,x轴
p.setTitle('y = sin(x)') # 表格的名字
curve = p.plot() # 绘制一个图形
idx = 0


# 定义函数
def plotData():
global idx # 内部作用域想改变外部域变量
tmp = np.sin(np.pi / 50 * idx) # sin动态函数曲线
# tmp = np.cos(np.pi / 50 * idx) #cos动态函数曲线
if len(data) < historyLength:
data.append(tmp)
else:
data[:-1] = data[1:] # 前移
data[-1] = tmp
curve.setData(data)
idx += 1


# 启动定时器
timer = pg.QtCore.QTimer()
timer.timeout.connect(plotData) # 定时调用plotData函数
timer.start(50) # 多少ms调用一次
# 注意exec后面的下划线
app.exec_()

sin(x)的函数曲线图画出来是这样的:

Pyqtgraph是Python平台上一种功能强大的2D/3D绘图库

然后我们将下面两行代码互换一下,就可以画出cos(x)函数的图像:

    # tmp = np.sin(np.pi / 50 * idx)  # sin动态函数曲线
    tmp = np.cos(np.pi / 50 * idx)  #cos动态函数曲线
Pyqtgraph是Python平台上一种功能强大的2D/3D绘图库

接下来,我们再画一个稍微复杂一点的图像,代码如下:

# -*- coding: utf-8 -*-
import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui
import numpy as np

# 数据,可自定义
x = np.linspace(-20, 20, 1000)
y = np.sin(x) / x # sin
# y = np.cos(x) / x #cos,省略

plot = pg.plot()
plot.setYRange(-1, 2) # y轴取值范围
plot.setWindowTitle('pyqtgraph example: text') # 表格名称
curve = plot.plot(x, y)

# 导入html格式的text静态标签,本次重点
text = pg.TextItem(
html='<div style="text-align: center">\
<span style="color: #FFF;">This is the</span>\
<br><span style="color: #FF0; font-size: 16pt;">PEAK</span>\
</div>', anchor=(-0.3, 0.5), angle=20, border='w', fill=(0, 0, 255, 100))
plot.addItem(text)
text.setPos(0, y.max())

# 画箭头
arrow = pg.ArrowItem(pos=(0, y.max()), angle=-45)
plot.addItem(arrow)

## 设置动画和曲线
curvePoint = pg.CurvePoint(curve)
plot.addItem(curvePoint)
# text2是动态显示text
text2 = pg.TextItem("test", anchor=(0.5, -1.0))
text2.setParentItem(curvePoint)
arrow2 = pg.ArrowItem(angle=90)
arrow2.setParentItem(curvePoint)

index = 0


def update():
global curvePoint, index
index = (index + 1) % len(x)
curvePoint.setPos(float(index) / (len(x) - 1))
text2.setText('[%0.1f, %0.1f]' % (x[index], y[index]))


timer = QtCore.QTimer()
timer.timeout.connect(update)
timer.start(10) # every 10ms

if __name__ == '__main__':
QtGui.QApplication.instance().exec_()
Pyqtgraph是Python平台上一种功能强大的2D/3D绘图库

pyqtgraph还提供了3D-GL模块,示例代码如下:

# -*- coding: utf-8 -*-
# 导出模块
from pyqtgraph.Qt import QtCore, QtGui
import pyqtgraph as pg
import pyqtgraph.opengl as gl
import numpy as np

## Create a GL View widget to display data,GL模块
app = QtGui.QApplication([])
w = gl.GLViewWidget()
w.show()
w.setWindowTitle('pyqtgraph example: GLSurfacePlot')
w.setCameraPosition(distance=50)

## Add a grid to the view
g = gl.GLGridItem()
g.scale(2, 2, 1)
g.setDepthValue(10)
w.addItem(g)

# P1图
z = pg.gaussianFilter(np.random.normal(size=(50, 50)), (1, 1))
p1 = gl.GLSurfacePlotItem(z=z, shader='shaded', color=(0.5, 0.5, 1, 1))
p1.scale(16. / 49., 16. / 49., 1.0)
p1.translate(-18, 2, 0)
w.addItem(p1)

# P2图
x = np.linspace(-8, 8, 50)
y = np.linspace(-8, 8, 50)
z = 0.1 * ((x.reshape(50, 1) ** 2) - (y.reshape(1, 50) ** 2))
p2 = gl.GLSurfacePlotItem(x=x, y=y, z=z, shader='normalColor')
p2.translate(-10, -10, 0)
w.addItem(p2)

# P3图
z = pg.gaussianFilter(np.random.normal(size=(50, 50)), (1, 1))
x = np.linspace(-12, 12, 50)
y = np.linspace(-12, 12, 50)
colors = np.ones((50, 50, 4), dtype=float)
colors[..., 0] = np.clip(np.cos(((x.reshape(50, 1) ** 2) + (y.reshape(1, 50) ** 2)) ** 0.5), 0, 1)
colors[..., 1] = colors[..., 0]

p3 = gl.GLSurfacePlotItem(z=z, colors=colors.reshape(50 * 50, 4), shader='shaded', smooth=False)
p3.scale(16. / 49., 16. / 49., 1.0)
p3.translate(2, -18, 0)
w.addItem(p3)

# P4图:动画
cols = 90
rows = 100
x = np.linspace(-8, 8, cols + 1).reshape(cols + 1, 1)
y = np.linspace(-8, 8, rows + 1).reshape(1, rows + 1)
d = (x ** 2 + y ** 2) * 0.1
d2 = d ** 0.5 + 0.1

phi = np.arange(0, np.pi * 2, np.pi / 20.)
z = np.sin(d[np.newaxis, ...] + phi.reshape(phi.shape[0], 1, 1)) / d2[np.newaxis, ...]

p4 = gl.GLSurfacePlotItem(x=x[:, 0], y=y[0, :], shader='heightColor', computeNormals=False, smooth=False)
p4.shader()['colorMap'] = np.array([0.2, 2, 0.5, 0.2, 1, 1, 0.2, 0, 2])
p4.translate(10, 10, 0)
w.addItem(p4)

index = 0


def update():
global p4, z, index
index -= 1
p4.setData(z=z[index % z.shape[0]])


timer = QtCore.QTimer()
timer.timeout.connect(update)
timer.start(30)

if __name__ == '__main__':
QtGui.QApplication.instance().exec_()

画出来的图形是这样的:

Pyqtgraph是Python平台上一种功能强大的2D/3D绘图库

再来画一个3D的图形,示例代码如下:

from pyqtgraph.Qt import QtCore, QtGui
import pyqtgraph.opengl as gl

app = QtGui.QApplication([])
w = gl.GLViewWidget()
w.opts['distance'] = 20
w.show()
w.setWindowTitle('pyqtgraph example: GLViewWidget')

ax = gl.GLAxisItem()
ax.setSize(5, 5, 5)
w.addItem(ax)

b = gl.GLBoxItem()
w.addItem(b)

ax2 = gl.GLAxisItem()
ax2.setParentItem(b)

b.translate(1, 1, 1)

if __name__ == '__main__':
# import sys
# if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
# QtGui.QApplication.instance().exec_()
QtGui.QApplication.instance().exec_() # 采用简化的,注意

画出来的图形如下:

Pyqtgraph是Python平台上一种功能强大的2D/3D绘图库

最后,再画一个立方体的图形,示例代码如下:

# -*- coding: utf-8 -*-
# 导出模块
from pyqtgraph.Qt import QtCore, QtGui
import pyqtgraph as pg
import pyqtgraph.opengl as gl
import numpy as np

# 基本初始化定义
app = QtGui.QApplication([])
w = gl.GLViewWidget()
w.show()
w.setWindowTitle('pyqtgraph example: GLMeshItem') # 标题名
w.setCameraPosition(distance=40) # 设置摄像机位置

g = gl.GLGridItem()
g.scale(2, 2, 1)
w.addItem(g)
## Example 1:
verts = np.array([
[0, 0, 0],
[2, 0, 0],
[1, 2, 0],
[1, 1, 1],
])
faces = np.array([
[0, 1, 2],
[0, 1, 3],
[0, 2, 3],
[1, 2, 3]
])
colors = np.array([
[1, 0, 0, 0.3],
[0, 1, 0, 0.3],
[0, 0, 1, 0.3],
[1, 1, 0, 0.3]
])

## Mesh item will automatically compute face normals.
m1 = gl.GLMeshItem(vertexes=verts, faces=faces, faceColors=colors, smooth=False)
m1.translate(5, 5, 0)
m1.setGLOptions('additive')
w.addItem(m1)

## Example 2:
## Array of vertex positions, three per face,3角体
verts = np.empty((36, 3, 3), dtype=np.float32)
theta = np.linspace(0, 2 * np.pi, 37)[:-1]
verts[:, 0] = np.vstack([2 * np.cos(theta), 2 * np.sin(theta), [0] * 36]).T
verts[:, 1] = np.vstack([4 * np.cos(theta + 0.2), 4 * np.sin(theta + 0.2), [-1] * 36]).T
verts[:, 2] = np.vstack([4 * np.cos(theta - 0.2), 4 * np.sin(theta - 0.2), [1] * 36]).T

## Colors are specified per-vertex
colors = np.random.random(size=(verts.shape[0], 3, 4))
m2 = gl.GLMeshItem(vertexes=verts, vertexColors=colors, smooth=False, shader='balloon',
drawEdges=True, edgeColor=(1, 1, 0, 1))
m2.translate(-5, 5, 0)
w.addItem(m2)

## Example 3:
## sphere,球
md = gl.MeshData.sphere(rows=10, cols=20)
colors = np.ones((md.faceCount(), 4), dtype=float)
colors[::2, 0] = 0
colors[:, 1] = np.linspace(0, 1, colors.shape[0])
md.setFaceColors(colors)
m3 = gl.GLMeshItem(meshdata=md, smooth=False) # , shader='balloon')
m3.translate(5, -5, 0)
w.addItem(m3)

# Example 4:
# wireframe,火焰
md = gl.MeshData.sphere(rows=4, cols=8)
m4 = gl.GLMeshItem(meshdata=md, smooth=False, drawFaces=False, drawEdges=True, edgeColor=(1, 1, 1, 1))
m4.translate(0, 10, 0)
w.addItem(m4)

# Example 5:
# cylinder,圆柱体
md = gl.MeshData.cylinder(rows=10, cols=20, radius=[1., 2.0], length=5.)
md2 = gl.MeshData.cylinder(rows=10, cols=20, radius=[2., 0.5], length=10.)
colors = np.ones((md.faceCount(), 4), dtype=float)
colors[::2, 0] = 0
colors[:, 1] = np.linspace(0, 1, colors.shape[0])
md.setFaceColors(colors)
m5 = gl.GLMeshItem(meshdata=md, smooth=True, drawEdges=True, edgeColor=(1, 0, 0, 1), shader='balloon')
colors = np.ones((md.faceCount(), 4), dtype=float)
colors[::2, 0] = 0
colors[:, 1] = np.linspace(0, 1, colors.shape[0])
md2.setFaceColors(colors)
m6 = gl.GLMeshItem(meshdata=md2, smooth=True, drawEdges=False, shader='balloon')
m6.translate(0, 0, 7.5)

m6.rotate(0., 0, 1, 1)
w.addItem(m5)
w.addItem(m6)

QtGui.QApplication.instance().exec_() # 这种方法:注意有三种方法结尾

画出来的图形如下:

Pyqtgraph是Python平台上一种功能强大的2D/3D绘图库

到这里,pyqtgraph就介绍完了。

发表评论

邮箱地址不会被公开。 必填项已用*标注