Pyqtgraph 中绘图的悬停工具

Posted

技术标签:

【中文标题】Pyqtgraph 中绘图的悬停工具【英文标题】:Hover Tool for plots in Pyqtgraph 【发布时间】:2021-10-21 03:15:38 【问题描述】:

我希望在将鼠标悬停在 pyqtgraph 图中的一条线上时显示数据信息,但无法让我的 sigpointsHovered 发出任何信号。这是我尝试做的一个简单示例:

from PySide6.QtWidgets import QMainWindow, QWidget, QApplication, QVBoxLayout
import pyqtgraph as pg

def hovered(self, points, ev):
    print("FOOO")
    
x = [1,2,3,4,5,6,7,8,9]
y = [0,1,2,3,4,5,6,7,8]

app = QApplication([])
window = QWidget()
layout = QVBoxLayout()

plot_widget = pg.PlotWidget()
plot_item = plot_widget.getPlotItem()
line = plot_item.plot(x,y)
line.sigPointsHovered.connect(hovered)

layout.addWidget(plot_widget)
window.setLayout(layout)
       
window.show()
app.exec_()

我已经尝试设置 "hoverable" = True 并多次阅读文档,但老实说我不知道​​为什么 sigPointsHovered 不起作用。

【问题讨论】:

【参考方案1】:

为什么sigPointsHovered 不起作用

简而言之:目前无法为PlotDataItem 类的ScatterPlotItem 设置“可悬停”参数。因此,无法使用sigPointsHovered

你可以在PlotDataItem类的函数updateItems的源代码中看到这一点。

解决方法

    如果你现在真的想要sigPointsHovered 之类的东西,而不是使用PlotWiget,而是使用ScatterPlotItem 并在初始化它或使用setData 函数时设置hoverable = True。运行python -m pyqtgraph.examples 并找到散点图示例以查看示例代码。

    但是,根据您的描述,我认为当您将鼠标悬停在“曲线”(而不是点)上时,您实际上想要做一些事情。目前,PlotCurveItem 没有实现hoverEvent,所以你可以尝试创建一个继承PlotCurveItem 的类并添加hoverEvent

让我告诉你如何做到这一点。

在本例中,当光标进入曲线时,颜色变为蓝色,离开曲线时变为白色。

import pyqtgraph as pg
from pyqtgraph import QtCore, QtGui


class HoverableCurveItem(pg.PlotCurveItem):
    sigCurveHovered = QtCore.Signal(object, object)
    sigCurveNotHovered = QtCore.Signal(object, object)

    def __init__(self, hoverable=True, *args, **kwargs):
        super(HoverableCurveItem, self).__init__(*args, **kwargs)
        self.hoverable = hoverable
        self.setAcceptHoverEvents(True)

    def hoverEvent(self, ev):
        if self.hoverable:
            if self.mouseShape().contains(ev.pos()):
                self.sigCurveHovered.emit(self, ev)
            else:
                self.sigCurveNotHovered.emit(self, ev)


class MainWindow(QtGui.QMainWindow):
    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)

        self.view = pg.GraphicsLayoutWidget()
        self.setCentralWidget(self.view)
        self.makeplot()

    def makeplot(self):
        x = [1, 2, 3, 4, 5, 6, 7, 8, 9]
        y = [0, 1, 2, 3, 4, 5, 6, 7, 8]
        plot = self.view.addPlot()
        self.plotitem = HoverableCurveItem(x, y, pen=pg.mkPen('w', width=10))
        self.plotitem.setClickable(True, width=10)
        self.plotitem.sigCurveHovered.connect(self.hovered)
        self.plotitem.sigCurveNotHovered.connect(self.leaveHovered)
        plot.addItem(self.plotitem)

    def hovered(self):
        print("cursor entered curve")
        self.plotitem.setPen(pg.mkPen('b', width=10))

    def leaveHovered(self):
        self.plotitem.setPen(pg.mkPen('w', width=10))


if __name__ == '__main__':
    import sys

    app = QtGui.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec())

编辑

需要setAcceptHoverEventTure

另外,在更新后的例子中,当光标进入曲线时,颜色变为蓝色,离开曲线时又变回白色。

【讨论】:

您好,非常感谢您的帮助!所以,你对悬停工具的假设是完全正确的,这正是我想要的。现在我尝试执行您的解决方法,但它没有打印“曲线悬停”语句。对于散点图示例,我也尝试了它们并且它们正在工作 - 我昨天也在考虑切换到它们,或者可能只是在图表上绘制两者。无论如何,我想我明白您的解决方法打算做什么,非常感谢您的意见! 我编辑了这个例子,希望这次对你有用。顺便说一句,请接受这是正确的答案。

以上是关于Pyqtgraph 中绘图的悬停工具的主要内容,如果未能解决你的问题,请参考以下文章

重新启动实时绘图时,pyqtgraph实时绘图中断

如何在pyqtgraph中缩放绘图

在pyqtgraph中实现实时绘图的最简单方法是啥

pyqtgraph:为绘图中的线条添加图例

在 PyQt4 中使用 PyQtGraph 进行实时绘图

pyqtgraph:具有与 matplotlib drawstyle 类似功能的绘图