
本文介绍如何仅依赖 PyQtGraph(不显式引入 PyQt)创建单窗口、多子图布局,并在同一子图中叠加绘制多条数据曲线,避免 pg.plot() 多次调用导致的多窗口问题。
本文介绍如何仅依赖 pyqtgraph(不显式引入 pyqt)创建单窗口、多子图布局,并在同一子图中叠加绘制多条数据曲线,避免 `pg.plot()` 多次调用导致的多窗口问题。
PyQtGraph 提供了轻量级的 GUI 封装机制,无需手动导入 PyQt5 或 PySide6 即可构建交互式绘图界面。核心在于使用 pg.GraphicsLayoutWidget 作为统一容器——它类似一个网格化画布,支持按行列添加多个 PlotItem(即独立坐标系/子图),每个 PlotItem 又可承载多个 PlotDataItem(即曲线)。
以下是一个完整、可运行的示例,展示如何在单个窗口中创建两个并排子图(左图绘制 'a' 和 'b' 两条曲线,右图单独绘制 'c'):
import pandas as pd
import pyqtgraph as pg
# 构造示例数据
a = [
{'a': 5, 'b': 10, 'c': 5},
{'a': 4, 'b': 0.5, 'c': 1},
{'a': 3.5, 'b': 15, 'c': 9},
{'a': 2.1, 'b': 5, 'c': 8},
{'a': 0.1, 'b': 1, 'c': 5},
]
df = pd.DataFrame(a)
# 创建应用实例(必须,即使不显式导入 PyQt)
app = pg.mkQApp()
# 创建图形布局容器(等效于“画布”)
fig_widget = pg.GraphicsLayoutWidget()
fig_widget.setWindowTitle("Multi-Plot Example with PyQtGraph")
# 创建两个 PlotItem(即两个独立坐标系)
p1 = pg.PlotItem(title="Subplot 1: a & b")
p2 = pg.PlotItem(title="Subplot 2: c")
# 将子图按网格位置添加到容器:(行, 列)
fig_widget.addItem(p1, 0, 0) # 第0行第0列
fig_widget.addItem(p2, 0, 1) # 第0行第1列
# 创建曲线对象(支持自动缩放、抗锯齿、交互式缩放平移)
curve_a = pg.PlotDataItem(df["a"].values, name="a", pen='r', symbol='o', symbolSize=5)
curve_b = pg.PlotDataItem(df["b"].values, name="b", pen='g', symbol='s', symbolSize=5)
curve_c = pg.PlotDataItem(df["c"].values, name="c", pen='b', symbol='t', symbolSize=5)
# 将曲线添加到对应子图
p1.addItem(curve_a)
p1.addItem(curve_b)
p2.addItem(curve_c)
# 显示图例(可选,需在子图中启用)
p1.addLegend()
p2.addLegend()
# 展示窗口并启动事件循环
fig_widget.show()
app.exec()
✅ 关键要点说明:
-
pg.mkQApp()自动初始化 Qt 应用(首次调用时创建),是单窗口模式的必要前提; -
GraphicsLayoutWidget是布局核心,替代了传统QGridLayout手动管理,支持响应式缩放; -
PlotItem是真正的“坐标轴”,具备标题、坐标轴标签、图例、缩放工具等完整功能; -
PlotDataItem比plot()返回的PlotCurveItem更灵活,支持符号、图例项、信号连接等高级特性; - ❌ 避免直接多次调用
pg.plot()—— 它每次都会新建一个PlotWidget窗口; - ❌ 不要误用
MultiPlotWidget(已弃用且不适用于此场景)或PlotWidget嵌套(非布局设计本意)。
通过该结构,你可轻松扩展为 N×M 网格、共享 X 轴、联动缩放(通过 p1.sigXRangeChanged.connect(...))、甚至嵌入图像/文本/ROI 等高级元素,真正发挥 PyQtGraph 在科学可视化中的高效与灵活性。











