PyQt5下PyqtGraph绘图优化问题:滚动显示与局部更新
PyQt5 + PyqtGraph 绘图问题解决方案
1. 实现跟随最新数据滚动显示(不缩放全部数据)
要让图表固定显示最近N个数据点、跟随新数据滚动,无需适配全部历史数据,可通过以下两种方式实现:
方式一:维护固定长度的数据缓冲区
直接限制存储的历史数据数量,只保留最近的N个点,同时手动设置X轴范围匹配当前显示区间:
import pyqtgraph as pg from PyQt5.QtWidgets import QWidget, QVBoxLayout, QPushButton import sys from PyQt5.QtCore import QTimer import numpy as np class PlotWindow(QWidget): def __init__(self): super().__init__() self.layout = QVBoxLayout() self.plot_widget = pg.PlotWidget() self.start_btn = QPushButton("Start") self.layout.addWidget(self.plot_widget) self.layout.addWidget(self.start_btn) self.setLayout(self.layout) # 初始化曲线和数据缓冲区 self.curve = self.plot_widget.plot() self.x_data = [] self.y_data = [] self.display_window = 50 # 固定显示最近50个数据点 self.timer = QTimer() self.timer.timeout.connect(self.update_plot) self.start_btn.clicked.connect(lambda: self.timer.start(1000)) self.current_x = 0 def update_plot(self): # 模拟获取新数据,替换为你的实际数据逻辑 new_x = self.current_x new_y = np.random.rand() * 10 self.current_x += 1 # 追加新数据并裁剪缓冲区 self.x_data.append(new_x) self.y_data.append(new_y) if len(self.x_data) > self.display_window: self.x_data = self.x_data[-self.display_window:] self.y_data = self.y_data[-self.display_window:] # 更新曲线并固定X轴范围 self.curve.setData(self.x_data, self.y_data) self.plot_widget.setXRange(min(self.x_data), max(self.x_data), padding=0) # 自动适配Y轴范围(可选) self.plot_widget.getViewBox().autoRange(axis=pg.ViewBox.YAxis) if __name__ == "__main__": app = QApplication(sys.argv) win = PlotWindow() win.show() sys.exit(app.exec_())
方式二:固定X轴显示窗口,自动跟随最新数据
不裁剪历史数据,而是固定X轴的显示宽度,每次新数据到来时平移X轴范围,始终包含最新数据:
# 初始化时补充设置 self.display_window_width = 50 # X轴固定显示50个单位宽度 self.plot_widget.getViewBox().setAutoRange(pg.ViewBox.YAxis) # Y轴自动适配 # 修改update_plot方法 def update_plot(self): new_x = self.current_x new_y = np.random.rand() * 10 self.current_x += 1 self.x_data.append(new_x) self.y_data.append(new_y) self.curve.setData(self.x_data, self.y_data) # 平移X轴范围,始终显示最后50个单位宽度的数据 if new_x > self.display_window_width: self.plot_widget.setXRange(new_x - self.display_window_width, new_x, padding=0)
2. 实现仅传入新数据的局部更新
PyqtGraph的PlotDataItem支持增量更新,无需每次重绘整个图表,以下是两种高效实现方式:
方式一:使用addPoints方法直接追加新数据
addPoints是专门用于增量添加数据的方法,只会更新新增的点,不会重绘整个曲线:
# 初始化曲线 self.curve = self.plot_widget.plot() # 修改update_plot方法 def update_plot(self): new_x = self.current_x new_y = np.random.rand() * 10 self.current_x += 1 # 仅传入新数据,局部更新曲线 self.curve.addPoints(x=[new_x], y=[new_y]) # 配合滚动显示的X轴设置(参考问题1的逻辑) if new_x > self.display_window_width: self.plot_widget.setXRange(new_x - self.display_window_width, new_x, padding=0)
方式二:使用numpy数组维护数据,优化更新效率
如果数据量较大,用numpy数组存储数据比Python列表更高效,setData内部会自动识别数据增量,避免全量重绘:
import numpy as np # 初始化时 self.x_data = np.array([], dtype=np.float64) self.y_data = np.array([], dtype=np.float64) self.curve = self.plot_widget.plot(self.x_data, self.y_data) # 修改update_plot方法 def update_plot(self): new_x = np.array([self.current_x], dtype=np.float64) new_y = np.array([np.random.rand() * 10], dtype=np.float64) self.current_x += 1 # 追加新数据 self.x_data = np.append(self.x_data, new_x) self.y_data = np.append(self.y_data, new_y) # 更新曲线,PyqtGraph会自动处理增量更新 self.curve.setData(self.x_data, self.y_data) # 滚动显示设置 if self.current_x > self.display_window_width: self.plot_widget.setXRange(self.current_x - self.display_window_width, self.current_x, padding=0)
内容的提问来源于stack exchange,提问作者Etozeigor
相关产品推荐
相关产品推荐

