pyqtgraph: add crosshair on mouse_x graph_y

北慕城南 提交于 2020-07-20 06:28:19

问题


I want to add a vertical line following the mouse_x position (working) and a horizontal line following the curve (and not mouse_y). In the pyqtgraph crosshair example, it shows how to add a crosshair following the mouse_x and mouse_y position. But that does not help that much. The following code sets the vertical line position to mouse_x postion. But i dont know how to set the horizontal line's postion to the curves current y position (depending on where the mouse x position is).

data1 = 10000 + 15000 * pg.gaussianFilter(np.random.random(size=10000), 10) + 3000 * np.random.random(size=10000)
def mouseMoved(evt):
    pos = evt[0]
    if p1.sceneBoundingRect().contains(pos):
        mousePoint = vb.mapSceneToView(pos)
        index = int(mousePoint.x())
        if index > 0 and index < len(data1):
            label.setText("<span style='font-size: 12pt'>x=%0.1f,   <span style='color: red'>y1=%0.1f</span>,   <span style='color: green'>y2=%0.1f</span>" % (mousePoint.x(), data1[index], data2[index]))

        vLine.setPos(mousePoint.x()) # here i set the vertical line's position to mouse_x position
        #hLinePos = vb.mapToView( vLine.pos() )
        hLine.setPos(data1[mousePoint.x()]) # <-- how do i set this horizontal line so it is kind of snaped to the curve

回答1:


Maybe this crosshair widget can point you in the right direction

from PyQt4 import QtCore, QtGui
import sys
import numpy as np
import pyqtgraph as pg
import random

"""Crosshair Plot Widget Example"""

class CrosshairPlotWidget(QtGui.QWidget):
    """Scrolling plot with crosshair"""

    def __init__(self, parent=None):
        super(CrosshairPlotWidget, self).__init__(parent)

        # Use for time.sleep (s)
        self.FREQUENCY = .025
        # Use for timer.timer (ms)
        self.TIMER_FREQUENCY = self.FREQUENCY * 1000

        self.LEFT_X = -10
        self.RIGHT_X = 0
        self.x_axis = np.arange(self.LEFT_X, self.RIGHT_X, self.FREQUENCY)
        self.buffer = int((abs(self.LEFT_X) + abs(self.RIGHT_X))/self.FREQUENCY)
        self.data = []

        self.crosshair_plot_widget = pg.PlotWidget()
        self.crosshair_plot_widget.setXRange(self.LEFT_X, self.RIGHT_X)
        self.crosshair_plot_widget.setLabel('left', 'Value')
        self.crosshair_plot_widget.setLabel('bottom', 'Time (s)')
        self.crosshair_color = (196,220,255)

        self.crosshair_plot = self.crosshair_plot_widget.plot()

        self.layout = QtGui.QGridLayout()
        self.layout.addWidget(self.crosshair_plot_widget)

        self.crosshair_plot_widget.plotItem.setAutoVisible(y=True)
        self.vertical_line = pg.InfiniteLine(angle=90)
        self.horizontal_line = pg.InfiniteLine(angle=0, movable=False)
        self.vertical_line.setPen(self.crosshair_color)
        self.horizontal_line.setPen(self.crosshair_color)
        self.crosshair_plot_widget.setAutoVisible(y=True)
        self.crosshair_plot_widget.addItem(self.vertical_line, ignoreBounds=True)
        self.crosshair_plot_widget.addItem(self.horizontal_line, ignoreBounds=True)

        self.crosshair_update = pg.SignalProxy(self.crosshair_plot_widget.scene().sigMouseMoved, rateLimit=60, slot=self.update_crosshair)

        self.start()

    def plot_updater(self):
        """Updates data buffer with data value"""

        self.data_point = random.randint(1,101)
        if len(self.data) >= self.buffer:
            del self.data[:1]
        self.data.append(float(self.data_point))
        self.crosshair_plot.setData(self.x_axis[len(self.x_axis) - len(self.data):], self.data)

    def update_crosshair(self, event):
        """Paint crosshair on mouse"""

        coordinates = event[0]  
        if self.crosshair_plot_widget.sceneBoundingRect().contains(coordinates):
            mouse_point = self.crosshair_plot_widget.plotItem.vb.mapSceneToView(coordinates)
            index = mouse_point.x()
            if index > self.LEFT_X and index <= self.RIGHT_X:
                self.crosshair_plot_widget.setTitle("<span style='font-size: 12pt'>x=%0.1f,   <span style='color: red'>y=%0.1f</span>" % (mouse_point.x(), mouse_point.y()))
            self.vertical_line.setPos(mouse_point.x())
            self.horizontal_line.setPos(mouse_point.y())

    def start(self):
        self.timer = QtCore.QTimer()
        self.timer.timeout.connect(self.plot_updater)
        self.timer.start(self.get_timer_frequency())

    def get_crosshair_plot_layout(self):
        return self.layout

    def get_timer_frequency(self):
        return self.TIMER_FREQUENCY

if __name__ == '__main__':
    # Create main application window
    app = QtGui.QApplication([])
    app.setStyle(QtGui.QStyleFactory.create("Cleanlooks"))
    mw = QtGui.QMainWindow()
    mw.setWindowTitle('Crosshair Plot Example')

    # Create and set widget layout
    # Main widget container
    cw = QtGui.QWidget()
    ml = QtGui.QGridLayout()
    cw.setLayout(ml)
    mw.setCentralWidget(cw)

    # Create crosshair plot
    crosshair_plot = CrosshairPlotWidget()

    ml.addLayout(crosshair_plot.get_crosshair_plot_layout(),0,0)

    mw.show()

    ## Start Qt event loop unless running in interactive mode or using pyside.
    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        QtGui.QApplication.instance().exec_()


来源:https://stackoverflow.com/questions/57359843/pyqtgraph-add-crosshair-on-mouse-x-graph-y

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!