PyQtGraph嵌入QWidget中动态绘制曲线(固定横坐标比例,坐标系可拖动查看历史数据)
效果
说明
我看网上的大部分教程都无法固定坐标系比例,导致数据一多就会显得图像拥挤,很不美观;且实现固定的比例的大多是是通过列表的数据偏移做的(即data[:-1] = data[1:]
),这种就会导致只能查看当前这段时间内的数据,无法查看历史数据。在查找了不少博客后,终于发现一种比较好的实现方式。
本文实现PyQtGraph在绘制过程中实时添加数据进行绘制,且固定横轴坐标系比例,并且可以在结束实时绘制后左右拖动坐标轴查看历史数据。
源码
import math
import sys
import pyqtgraph as pg
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout
from PyQt5.QtCore import QTimer
class Draw(QWidget):
def __init__(self):
super().__init__()
self.timer = None
self.resize(800, 800)
self.setWindowTitle("Sin's dynamic curve")
# 1.绘制板基本设置
pg.setConfigOptions(leftButtonPan=True, antialias=True) # 允许鼠标左键拖动画面,并启用抗锯齿
pg.setConfigOption('background', 'w') #初始的背景(白)
# 2.创建 6 个坐标点组
self.xRange = 80 # x坐标显示宽度
self.x_points = list(range(0, 60))
self.y_points = []
for i in range(len(self.x_points)):
self.y_points.append(math.sin(i / 10))
# 点型 ['o', 's', 't', 't1', 't2', 't3','d', '+', 'x', 'p', 'h', 'star']
# 点色 ['b', 'g', 'r', 'c', 'm', 'y', 'k', 'd', 'l', 's']
# 3.创建窗口,设置绘图样式
self.pw = pg.PlotWidget(self)
self.plot_data = self.pw.plot(self.x_points, self.y_points, pen=pg.mkPen(color=(0, 0, 100), width=3),
symbol='s', symbolBrush='r')
# 这里的 self.plot_data 是用于后续增加点的绘制
# 4.将绘图板和按钮嵌入主窗体中
self.start_btn = QPushButton('Start', self)
self.start_btn.clicked.connect(self.timerStart)
self.stop_btn = QPushButton('Stop', self)
self.stop_btn.clicked.connect(self.timerStop)
self.v_layout = QVBoxLayout()
self.v_layout.addWidget(self.pw)
self.v_layout.addWidget(self.start_btn)
self.v_layout.addWidget(self.stop_btn)
self.setLayout(self.v_layout)
# 5.设置定时器
self.timer = QTimer(self)
self.timer.timeout.connect(self.newPointPlot)
def timerStart(self):
self.timer.start(100) # ms
def timerStop(self):
self.timer.stop()
def newPointPlot(self):
# 绘制时失能鼠标控制
self.pw.setMouseEnabled(x=False, y=False) # 失能x,y轴控制
self.x_points.append(len(self.x_points)) # +1
self.y_points.append(math.sin(self.x_points[-1] / 10))
self.plot_data.setData(self.x_points, self.y_points) # 重新绘制
if(len(self.x_points) > self.xRange):
self.pw.setXRange(len(self.x_points) - self.xRange, len(self.x_points)) # 固定x坐标轴宽度
# 结束时使能鼠标控制
self.pw.setMouseEnabled(x=True, y=False) # 使能x轴控制,失能y轴控制
if __name__ == '__main__':
app = QApplication(sys.argv)
demo = Draw()
demo.show()
sys.exit(app.exec_())