你如何增加 matplotlib Line2D 艺术家的 pickradius?
How do you increase the pickradius of a matplotlib Line2D artist?
我想创建一个情节,其中每个点都是可以挑选的个人艺术家。这是我目前的解决方案:
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 which you can use to come up with your own contains
method. But I don't know how to do that. I was hoping I could learn from how the default contains
method is implemented and looked at the source code,但不幸的是这并没有解释任何东西。
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'
)
我想创建一个情节,其中每个点都是可以挑选的个人艺术家。这是我目前的解决方案:
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 which you can use to come up with your own contains
method. But I don't know how to do that. I was hoping I could learn from how the default contains
method is implemented and looked at the source code,但不幸的是这并没有解释任何东西。
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'
)