【发布时间】: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