Good day. This question is a follow-up of Why does legend-picking only works for `ax.twinx()` and not `ax`?.
The minimal code provided below plots two curves respectively on ax1
and ax2 = ax1.twinx()
, their legend boxes are created and the bottom legend is moved to the top ax so that picker events can be used. Clicking on a legend item will hide/show the associated curve.
If ax.scatter(...)
is used that works fine. If ax.plot(...)
is used instead, legend picking suddenly breaks. Why? Nothing else is changed so that's quite confusing. I have tested several other plotting methods and none of them work as expected.
Here is a video of it in action: https://imgur.com/qsPYHKc.mp4
import matplotlib.pyplot as plt
import numpy as np
fig, ax1 = plt.subplots()
ax2 = ax1.twinx()
X = np.linspace(0, 2*np.pi, 100)
Y1 = X**0.5 * np.sin(X)
Y2 = -np.cos(X)
# This is a quick way to change the plotting function, simply modify n.
n = 0
function, container = [("scatter", "collections"),
("plot", "lines"),
("bar", "patches"),
("barbs", "collections"),
("quiver", "collections")][n]
getattr(ax1, function)(X, Y1, color="green", label="$Y_1$")
getattr(ax2, function)(X, Y2, color="red", label="$Y_2$")
# Put both legends on ax2 so that pick events also work for ax1's legend.
legend1 = ax1.legend(loc="upper left")
legend2 = ax2.legend(loc="upper right")
legend1.remove()
ax2.add_artist(legend1)
for n, legend in enumerate((legend1, legend2)):
legend_item = legend.legendHandles[0]
legend_item.set_gid(n+1)
legend_item.set_picker(10)
# When a legend element is picked, hide/show the associated curve.
def on_graph_pick_event(event):
gid = event.artist.get_gid()
print(f"Picked Y{gid}'s legend.")
ax = {1: ax1, 2: ax2}[gid]
for artist in getattr(ax, container):
artist.set_visible(not artist.get_visible())
plt.draw()
fig.canvas.mpl_connect("pick_event", on_graph_pick_event)