如何增加matplotlib Line2D艺术家的拾取半径?

2024-04-25 16:31:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我想创建一个情节,其中每个点是一个单独的艺术家,可以选择。这是我当前的解决方案:

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

from PyQt5.QtWidgets import QDialog, QApplication, QVBoxLayout


class MainWindow(QDialog):
    def __init__(self):
        super().__init__()
        self.fig, self.ax = plt.subplots()
        self.canvas = FigureCanvas(self.fig)

        a = [np.random.randint(100) for _ in range(100)]
        b = [np.random.randint(100) for _ in range(100)]
        self.artists = []
        self.last_artist = None
        for x, y in zip(a, b):
            artist = self.ax.plot(
                x, y, 'o', picker=True, pickradius=6, color='#ff4500'
            )
            self.artists += artist

        self.canvas.draw()

        self.cid_motion = self.fig.canvas.mpl_connect(
            'motion_notify_event', self.hover
        )

        layout = QVBoxLayout()
        layout.addWidget(self.canvas)
        self.setLayout(layout)

    def hover(self, event):
        if event.inaxes == self.ax:
            ind = 0
            cont = None
            while (
                ind in range(len(self.artists))
                and not cont
            ):
                artist = self.artists[ind]
                cont, _ = artist.contains(event)
                if cont:
                    if artist is not self.last_artist:
                        if self.last_artist is not None:
                            self.last_artist.set_path_effects(
                                [PathEffects.Normal()]
                            )
                            self.last_artist.set_zorder(2)
                        artist.set_path_effects(
                            [PathEffects.withStroke(
                                linewidth=7, foreground="c", alpha=0.4
                            )]
                        )
                        artist.set_zorder(3)
                        self.last_artist = artist
                ind += 1

            if not cont and self.last_artist is not None:
                self.last_artist.set_path_effects([PathEffects.Normal()])
                self.last_artist.set_zorder(2)
                self.last_artist = None
            self.canvas.draw()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    GUI = MainWindow()
    GUI.show()
    sys.exit(app.exec_())

但是,如果将精确地悬停在数据点的中心上方,则突出显示起作用,如果增加pickradius,则无关紧要。所以我想也许我可以改变contains方法,但我不知道怎么做。我发现matplotlibArtists提供了一个^{} method,您可以使用它来创建自己的contains方法。但我不知道怎么做。我希望我可以从默认的contains方法的实现中学习,并查看source code,但不幸的是,这没有解释任何内容


Tags: inimportselfnoneeventifartistas
1条回答
网友
1楼 · 发布于 2024-04-25 16:31:29

pickradius结合picker作为bool应该实现您想要的。然而,它并没有这样做。另一方面,picker如果定义为浮点,则用作点中的拾取半径。因此,将公差直接指定给picker可以使事情正常进行。更改以下行:

        artist = self.ax.plot(
            x, y, 'o', picker=True, pickradius=6, color='#ff4500'
        )

        artist = self.ax.plot(
            x, y, 'o', picker=6, color='#ff4500'
        )

相关问题 更多 >