PyQt5中为PyQtGraph图表坐标轴设置不同刻度的方法
为PyQtGraph实现双Y轴刻度显示
问题背景
我基于PyQt5开发了一个界面,点击“开始”按钮后通过PyQtGraph绘制三条曲线:
- 绿色、蓝色曲线:Y轴范围0-200
- 红色曲线:Y轴范围0-0.5
需要在图表的Y轴同时显示这两组刻度标尺。
实现方案
PyQtGraph支持添加额外的右侧Y轴,我们可以将绿色、蓝色曲线绑定到左侧默认Y轴,红色曲线绑定到右侧新增Y轴,分别配置两组轴的范围和刻度。
修改步骤
- 扩展Graph类,添加右侧Y轴
在Graph初始化方法中,启用右侧Y轴并配置样式,使其与对应曲线颜色匹配,方便区分。 - 关联曲线到对应Y轴
初始化红色曲线时,指定其使用右侧Y轴。 - 设置双Y轴的范围
分别为左侧轴设置0-200范围,右侧轴设置0-0.5范围,替代原来统一的Y轴范围设置。
修改后的完整代码
from pyqtgraph import PlotWidget import pyqtgraph from PyQt5 import QtCore from PyQt5.QtCore import Qt, QThread, QTimer, QObject, pyqtSignal from PyQt5.QtWidgets import QHBoxLayout, QMainWindow, QPushButton, QVBoxLayout, QWidget, QApplication import sys import random import numpy as np def get_kl_test(): choices = [50, 50, 50, 51, 51, 51, 52, 52, 52] return [random.choice(choices) for i in range(11)] def get_iopd_test(): choices = [0.05, 0.1, 0.15, 0.2, 0.25, 0.3] return random.choice(choices) class Graph(PlotWidget): def __init__(self): super().__init__() self.setBackground('white') self.addLegend() self.showGrid(x=True, y=True) # 启用并配置右侧Y轴 self.right_axis = self.plotItem.getAxis('right') self.plotItem.showAxis('right') # 设置右侧轴颜色与红色曲线一致 self.right_axis.setPen(pyqtgraph.mkPen(color='red')) self.right_axis.setTextPen(pyqtgraph.mkPen(color='red')) # 设置左侧Y轴范围(绿、蓝曲线) self.plotItem.getAxis('left').setRange(0, 200) # 设置右侧Y轴范围(红曲线) self.right_axis.setRange(0, 0.5) class ReadingWorker(QObject): update_graph = pyqtSignal(list, list, list, list) def __init__(self): super().__init__() self.time_from_start = 0 self.time_values = [] self.green_values = [] self.blue_values = [] self.red_values = [] def run(self): self.read() self.update_time() def read(self): ipd_values = get_kl_test() iopd_value = get_iopd_test() self.green_values.append(ipd_values[0]) self.blue_values.append(ipd_values[1]) self.red_values.append(iopd_value) self.time_values.append(self.time_from_start) self.update_graph.emit( self.green_values, self.blue_values, self.red_values, self.time_values) QTimer.singleShot(1000, self.read) def update_time(self): self.time_from_start += 1 QTimer.singleShot(1000, self.update_time) class MainWindow(QMainWindow): def __init__(self): super().__init__() self.central_widget = QWidget(self) self.setGeometry(50, 50, 1300, 700) self.setCentralWidget(self.central_widget) self.layout_main_window = QVBoxLayout() self.central_widget.setLayout(self.layout_main_window) self.layout_toolbar = QHBoxLayout() self.layout_toolbar.addStretch(1) self.btn_start = QPushButton("开始") self.btn_start.clicked.connect(self.start) self.layout_toolbar.addWidget(self.btn_start) self.layout_main_window.addLayout(self.layout_toolbar) self.graph = Graph() self.layout_main_window.addWidget(self.graph) self.setup_graphs() self.window_size = 50 def start(self): self.reading_thread = QThread(parent=self) self.reading_widget = ReadingWorker() self.reading_widget.moveToThread(self.reading_thread) self.reading_widget.update_graph.connect(self.draw_graph) self.reading_thread.started.connect(self.reading_widget.run) self.reading_thread.start() def setup_graphs(self): pen_ipd_1 = pyqtgraph.mkPen(color='green', width=4) pen_ipd_2 = pyqtgraph.mkPen(color='blue', width=4, style=Qt.DashDotLine) pen_iopd = pyqtgraph.mkPen(color='red', width=4, style=Qt.DashLine) # 绿、蓝曲线绑定左侧默认Y轴 self.line_ipd_1 = pyqtgraph.PlotCurveItem([], [], pen=pen_ipd_1, name='曲线1') self.line_ipd_2 = pyqtgraph.PlotCurveItem([], [], pen=pen_ipd_2, name='曲线2') # 红色曲线绑定右侧Y轴 self.line_iopd = pyqtgraph.PlotCurveItem([], [], pen=pen_iopd, name='曲线3') self.line_iopd.setParentItem(self.graph.plotItem) self.line_iopd.setYAxis(self.graph.right_axis) self.graph.plotItem.addItem(self.line_ipd_1) self.graph.plotItem.addItem(self.line_ipd_2) self.graph.plotItem.addItem(self.line_iopd) @QtCore.pyqtSlot(list, list, list, list) def draw_graph(self, ipd_1_values, ipd_2_values, iopd_values, time_values): x, y = self.line_ipd_1.getData() x = np.append(x, time_values[-1]) self.line_ipd_1.setData(y=np.append(y, ipd_1_values[-1]), x=x) _, y = self.line_ipd_2.getData() self.line_ipd_2.setData(y=np.append(y, ipd_2_values[-1]), x=x) _, y = self.line_iopd.getData() self.line_iopd.setData(y=np.append(y, iopd_values[-1]), x=x) # 保持X轴滚动窗口 if len(x) > 0 and x[-1] - x[0] > self.window_size: self.graph.plotItem.setXRange(x[-1]-self.window_size, x[-1]) if __name__ == '__main__': app = QApplication(sys.argv) app.setStyle('Fusion') main_window = MainWindow() main_window.show() sys.exit(app.exec_())
关键修改说明
- 在
Graph类中,通过plotItem.showAxis('right')启用右侧轴,并设置颜色与红色曲线匹配,提升辨识度。 - 分别为左右轴设置对应Y范围,确保曲线显示在合理区间内。
- 在
setup_graphs方法中,通过line_iopd.setYAxis(self.graph.right_axis)将红色曲线绑定到右侧Y轴,实现双轴数据关联。
内容的提问来源于stack exchange,提问作者Etozeigor
相关产品推荐
相关产品推荐

