python PyQt5中PyQtGraph图表轴的不同比例

rnmwe5a2  于 2023-06-04  发布在  Python
关注(0)|答案(1)|浏览(214)

我在PyQt 5上有一个界面,在其中,通过按下Start按钮,构建一个图形,这是我使用PyQtGraph制作的。图表上画了三条线。绿色和蓝色具有0到200的y轴范围,而红色具有0到0.5的范围。如何为不同的线设置不同的刻度,以及在Y轴上指定两个值刻度-从0到200和从0到0.5?

from pyqtgraph import PlotWidget
import pyqtgraph
from PyQt5 import QtCore
from PyQt5.QtCore import Qt, QThread, QTimer, QObject, pyqtSignal, QTimer
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]
    list = [random.choice(choices) for i in range(11)]
    return list

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)
        self.setYRange(0, 255, padding=0)

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)
        self.line_ipd_1 = pyqtgraph.PlotCurveItem([], [], pen=pen_ipd_1, name='1')
        self.line_ipd_2 = pyqtgraph.PlotCurveItem([], [], pen=pen_ipd_2, name='2')
        self.line_iopd = pyqtgraph.PlotCurveItem([], [], pen=pen_iopd, name='3')
        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)
        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_())
8zzbczxx

8zzbczxx1#

查看MultiplePlotAxes.py示例。
要在右侧添加另一个轴,请更改setup_graphs函数并添加update_views

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)
        self.line_ipd_1 = pyqtgraph.PlotCurveItem([], [], pen=pen_ipd_1, name='1')
        self.line_ipd_2 = pyqtgraph.PlotCurveItem([], [], pen=pen_ipd_2, name='2')
        self.line_iopd = pyqtgraph.PlotCurveItem([], [], pen=pen_iopd, name='3')
        self.graph.plotItem.addItem(self.line_ipd_1)
        self.graph.plotItem.addItem(self.line_ipd_2)

        self.vb = pyqtgraph.ViewBox()
        self.pi = self.graph.plotItem
        self.pi.showAxis('right')
        self.pi.scene().addItem(self.vb)
        self.pi.getAxis('right').linkToView(self.vb)
        self.vb.setXLink(self.pi)

        self.update_views()
        self.pi.vb.sigResized.connect(self.update_views)
        self.vb.addItem(self.line_iopd)

        self.pi.setYRange(0,200)
        self.vb.setYRange(0,0.5)
        self.graph.plotItem.legend.addItem(self.line_iopd, self.line_iopd.name())

    def update_views(self):
        self.vb.setGeometry(self.pi.vb.sceneBoundingRect())
        self.vb.linkedViewChanged(self.pi.vb, self.vb.XAxis)

结果:

编辑以模拟缩放两个y轴(也可能有内置的东西,这里的padding真的很烦人):

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)
        self.line_ipd_1 = pyqtgraph.PlotCurveItem([], [], pen=pen_ipd_1, name='1')
        self.line_ipd_2 = pyqtgraph.PlotCurveItem([], [], pen=pen_ipd_2, name='2')
        self.line_iopd = pyqtgraph.PlotCurveItem([], [], pen=pen_iopd, name='3')
        self.graph.plotItem.addItem(self.line_ipd_1)
        self.graph.plotItem.addItem(self.line_ipd_2)

        self.vb = pyqtgraph.ViewBox()
        self.pi = self.graph.plotItem
        self.pi.showAxis('right')
        self.pi.scene().addItem(self.vb)
        self.pi.getAxis('right').linkToView(self.vb)
        self.vb.setXLink(self.pi)

        self.update_views()
        self.pi.vb.sigResized.connect(self.update_views)
        self.vb.addItem(self.line_iopd)

        self.pi.setYRange(0,255, padding=0)
        self.vb.setYRange(0,0.5, padding=0)

        self.align = None
        self.update_secondary()
        self.pi.vb.sigYRangeChanged.connect(self.update_secondary)

        self.graph.plotItem.legend.addItem(self.line_iopd, self.line_iopd.name())

    def update_views(self):
        self.vb.setGeometry(self.pi.vb.sceneBoundingRect())
        self.vb.linkedViewChanged(self.pi.vb, self.vb.XAxis)

    def update_secondary(self):
        if self.align is None:
            self.align = [self.pi.getAxis('left').range, self.pi.getAxis('right').range]
        factor = (self.align[1][1]-self.align[1][0])/(self.align[0][1]-self.align[0][0])
        newRangeLeft = self.pi.getAxis('left').range
        newRangeRightMin = self.align[1][0]-(self.align[0][0]-newRangeLeft[0])*factor
        newRangeRightMax = self.align[1][1]+(newRangeLeft[1]-self.align[0][1])*factor
        self.vb.setYRange(newRangeRightMin, newRangeRightMax, padding=0)

相关问题