我正在一个图中画两条线,我想在单击这些线时画一条垂直线。 我想要的是单击行“y1”时调用回调“on_pick_line1”,单击行 y2 时调用回调“on_pick_line2”。
文档中的所有示例都展示了如何将回调绑定到画布的“on_pick”事件,但它不知道单击了哪一行。
我编写了 Pick_dispatcher 类,它将“on_pick”事件路由到我的回调。该解决方案有效,但在我看来很复杂。
有没有办法将回调“on_pick_line1”直接绑定到行“y1”等等?
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
class Pick_dispatcher():
"""Pick callbacks register themselfs into the dispatcher, then they'll get called"""
def __init__(self):
self.callbacks = {}
def register_callback(self, artist, func):
self.callbacks[artist] = func
def unregister_callback(self, artist, func):
del self.callbacks[artist]
def __call__(self, event):
artist = event.artist
print("Dispatcher calling ", artist.get_label())
self.callbacks[artist](event)
def on_pick_line1(event):
artist = event.artist
i_sel = event.ind # list of indexes selected vertices
i_med = i_sel[len(i_sel) // 2] # index of median vertex
x = artist.get_xdata()[i_med] # median vertex
ax = artist.axes
ax.axvline(x, ls='--', lw=1, color='blue')
artist.get_figure().canvas.draw_idle()
def on_pick_line2(event):
artist = event.artist
i_sel = event.ind
i_med = i_sel[len(i_sel) // 2]
x = artist.get_xdata()[i_med]
ax = artist.axes
ax.axvline(x, ls='--', lw=1, color='red')
artist.get_figure().canvas.draw_idle()
if __name__ == "__main__":
# Sample traces
x = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
y1 = np.array([0, 0, 0, 1, 2, 3, 4, 5, 6, 6, 6, 6])
y2 = np.array([0, 0, 1, 2, 3, 4, 5, 5, 5, 5, 5, 5])
# Prepare plot
fig, ax = plt.subplots()
pick_dispatcher = Pick_dispatcher()
tolerance = 5 # points
f, = ax.plot(x, y1, marker=".", ms=2, lw=1, label='y1', picker=True, pickradius=tolerance)
pick_dispatcher.register_callback(f, on_pick_line1)
g, = ax.plot(x, y2, marker=".", ms=2, lw=1, label='y2', picker=True, pickradius=tolerance)
pick_dispatcher.register_callback(g, on_pick_line2)
plt.legend()
fig.canvas.callbacks.connect('pick_event', pick_dispatcher)
plt.show()
import numpy as np
import matplotlib.pyplot as plt
def on_pick_line1(event):
artist = event.artist
i_sel = event.ind # list of indexes selected vertices
i_med = i_sel[len(i_sel) // 2] # index of median vertex
x = artist.get_xdata()[i_med] # median vertex
ax = artist.axes
ax.axvline(x, ls='--', lw=1, color='blue')
artist.get_figure().canvas.draw_idle()
def on_pick_line2(event):
artist = event.artist
i_sel = event.ind
i_med = i_sel[len(i_sel) // 2]
x = artist.get_xdata()[i_med]
ax = artist.axes
ax.axvline(x, ls='--', lw=1, color='red')
artist.get_figure().canvas.draw_idle()
if __name__ == "__main__":
# Sample traces
x = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
y1 = np.array([0, 0, 0, 1, 2, 3, 4, 5, 6, 6, 6, 6])
y2 = np.array([0, 0, 1, 2, 3, 4, 5, 5, 5, 5, 5, 5])
# Prepare plot
fig, ax = plt.subplots()
tolerance = 5 # points
line1, = ax.plot(x, y1, marker=".", ms=2, lw=1, label='y1', picker=True, pickradius=tolerance)
line2, = ax.plot(x, y2, marker=".", ms=2, lw=1, label='y2', picker=True, pickradius=tolerance)
# Bind callbacks directly
def on_pick(event):
if event.artist == line1:
on_pick_line1(event)
elif event.artist == line2:
on_pick_line2(event)
fig.canvas.mpl_connect('pick_event', on_pick)
plt.legend()
plt.show()