Matplotlib .contains 方法不再适用于更新的环境

问题描述 投票:0回答:1

.contains 方法适用于 matplotlib 3.4.3 和 python 3.8.19 不再适用于更新的环境。

该方法返回一个布尔值和字典。 即使鼠标悬停在数据点上,它也始终返回 False 和空字典。

使用 matplotlib 版本 3.4.3 和 python 版本 3.8.19 迁移回原始环境,以确认问题是由环境更新引起的。

查找相关帖子并挖掘 matplotlib 库以尝试排除故障。终于找到了创建注释的替代方法,但我想知道为什么 .contains 方法不再起作用。

最小工作示例:

import sys
import numpy
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt5agg import \
    FigureCanvasQTAgg as FigureCanvas


from PyQt5.QtWidgets import (
    QApplication,
    QMainWindow,
    QVBoxLayout,
    QWidget,
    )

class MainWindow(QMainWindow):

    def __init__(self):
        super().__init__()

        self.setWindowTitle("Live Charts")
        self.statusbar = self.statusBar()
        self.setCentralWidget(GraphWidget())

class GraphWidget(QWidget):

    def __init__(self):
        super().__init__()

        self.prev_ind = None
        self.canvas = FigureCanvas()
        vertical_layout = QVBoxLayout(self)
        vertical_layout.addWidget(self.canvas)

        self.fig = plt.figure(figsize=(4, 4), dpi=100)
        self.fig.set_tight_layout(True)
        self.ax = self.fig.add_subplot()
        self.canvas.figure = self.fig

        x = numpy.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
        y = numpy.array([1, 2, 3, 4, 5, 6, 7, 8, 9])

        self.sc = self.ax.scatter(x,
                                  y,
                                  edgecolors='Midnightblue',
                                  color='cornflowerblue')

        self.annot = self.ax.annotate("", (x, y),
                                      annotation_clip=True,
                                      size=7, textcoords="offset points",
                                      bbox=dict(boxstyle="round", fc="w"),
                                      arrowprops=dict(arrowstyle="->"))

        self.annot.set_visible(False)
        self.fig.canvas.mpl_connect("motion_notify_event", self.hover)
        self.canvas.draw()

    def hover(self, event):
        vis = self.annot.get_visible()
        if event.inaxes == self.ax:
            print("event: " + str(event))
            self.cont, self.ind = self.sc.contains(event)
            print("self.ind: " + str(self.ind))
            print("self.cont: " + str(self.cont))
            if self.cont:
                self.update_annot(self.ind)
                self.annot.set_visible(True)
                self.prev_ind = self.ind
                self.canvas.draw()
            else:
                if vis:
                    self.annot.set_visible(False)
                    self.prev_ind = None
                    self.canvas.draw()

if __name__ == '__main__':

    app = QApplication(sys.argv)
    window = MainWindow()
    window.showMaximized()
    window.activateWindow()
    sys.exit(app.exec())
python matplotlib pyqt5 annotations
1个回答
0
投票

问题似乎出在我构建图表/类的方式上。

这篇文章有帮助:如何在 pyqt5 中使 matplotlib 绘图具有交互性

import sys
import numpy as np
from matplotlib.backends.backend_qt5agg import \
    FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure

from PyQt5.QtWidgets import (
    QApplication,
    QMainWindow,
    QVBoxLayout,
    QWidget,
    )

class MainWindow(QMainWindow):

    def __init__(self):
        super().__init__()

        self.setWindowTitle("Live Charts")
        self.statusbar = self.statusBar()
        self.setCentralWidget(GraphWidget())


class GraphWidget(FigureCanvas):

    def __init__(self):
        fig = Figure()
        super(GraphWidget, self).__init__(fig)

        self.prev_ind = None
        vertical_layout = QVBoxLayout(self)
        vertical_layout.addWidget(self)

        self.x = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
        self.y = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])

        self.ax = self.figure.add_subplot()
        self.ax.scatter(self.x, self.y)

        self.annot = self.ax.annotate("", (self.x, self.y),
                                      annotation_clip=True,
                                      size=7, textcoords="offset points",
                                      bbox=dict(boxstyle="round", fc="w"),
                                      arrowprops=dict(arrowstyle="->"))

        self.annot.set_visible(False)
        fig.canvas.mpl_connect("motion_notify_event", self.hover)

        self.draw()

    def hover(self, event):
        vis = self.annot.get_visible()
        if event.inaxes == self.ax:
            self.cont, self.ind = self.ax.collections[0].contains(event)
            print("self.ind: " + str(self.ind))
            print("self.cont: " + str(self.cont))
            if (self.prev_ind is None or self.ind.values()
                    != self.prev_ind.values()):
                self.x_data = event.xdata
                self.y_data = event.ydata
                if self.cont:
                    self.update_annot(self.ind)
                    self.annot.set_visible(True)
                    self.prev_ind = self.ind
                    self.draw()
                else:
                    if vis:
                        self.annot.set_visible(False)
                        self.prev_ind = None
                        self.draw()
            else:
                pass
© www.soinside.com 2019 - 2024. All rights reserved.