You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 01:04:58