【问题标题】:How do you increase the pickradius of a matplotlib Line2D artist?如何增加 matplotlib Line2D 艺术家的pickradius?
【发布时间】:2020-01-24 15:09:50
【问题描述】:

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

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 方法,但我不知道怎么做。我发现 matplotlib Artists 带有一个 set_contains method,您可以使用它来提出您自己的 contains 方法。但我不知道该怎么做。我希望我可以学习默认的contains 方法是如何实现的,并查看了source code,但不幸的是,这并没有说明什么。

【问题讨论】:

    标签: python matplotlib contains picker


    【解决方案1】:

    pickradiuspicker 结合为 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'
            )
    

    【讨论】:

    • 可能。我是matplotlib 的新手。只是帮助人们得到一个钩子。这就像第二个有效的解决方案。我会记下这些并向社区报告,看看它们是否真的是一个错误。
    • 请注意True1 相同。如果picker 是一个数字,则pickradius 设置为该数字。由于关键字参数以相反的顺序读取,picker=True, pickradius=6 仅表示:“将半径设置为 6;然后将半径设置为 1。”
    • @ImportanceOfBeingErnest 感谢您的澄清。 OPs 问题似乎很常见。关键字参数的阅读顺序会产生这样的问题,这不是违反直觉吗?
    • 哦,可能是。但还要注意 picker=True 并不真正受支持。它只是巧合。
    • 我明白了。所以这要么是文档中的错误,要么是代码中的错误。因为没有明确检查 bool 存在。 (实际上,您可以将picker="yes", pickradius=10 放在那里,它会起作用。)请随意创建一个关于此的问题,因为有些东西需要更改。
    猜你喜欢
    • 2012-05-16
    • 2017-02-19
    • 1970-01-01
    • 1970-01-01
    • 2017-05-24
    • 2012-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多