I'm trying to code a legend picker for matplotlib errorbar plots similar to this example. I want to be able to click on the errorbars / datapoints in the legend to toggle their visibility in the axis. The problem is that the legend object returned by plt.legend() does not contain any data on the artists used in creating the legend. If I for eg. do:
import numpy as np
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
x = np.linspace(0,10,100)
y = np.sin(x) + np.random.rand(100)
yerr = np.random.rand(100)
erbpl1 = ax.errorbar(x, y, yerr=yerr, fmt='o', label='A')
erbpl2 = ax.errorbar(x, 0.02*y, yerr=yerr, fmt='o', label='B')
leg = ax.legend()
From here it seems impossible to access the legend's artists by using the leg object. Normally, one can do this with simpler legends, eg:
plt.plot(x, y, label='whatever')
leg = plt.legend()
proxy_lines = leg.get_lines()
gives you the Line2D objects used in the legend. With errorbar plots, however, leg.get_lines() returns an empty list. This kind of makes sense because plt.errorbar returns a matplotlib.container.ErrorbarContainer object (which contains the data points, errorbar end caps, errorbar lines). I would expect the legend to have a similar data container, but i cant see this. The closest I could manage was leg.legendHandles which points to the errorbar lines, but not data points nor the end caps. If you can pick the legends, you can map them to the original plots with a dict and use the following functions to turn the errorbars on/off.
def toggle_errorbars(erb_pl):
points, caps, bars = erb_pl
vis = bars[0].get_visible()
for line in caps:
line.set_visible(not vis)
for bar in bars:
bar.set_visible(not vis)
return vis
def onpick(event):
# on the pick event, find the orig line corresponding to the
# legend proxy line, and toggle the visibility
legline = event.artist
origline = lined[legline]
vis = toggle_errorbars(origline)
## Change the alpha on the line in the legend so we can see what lines
## have been toggled
if vis:
legline.set_alpha(.2)
else:
legline.set_alpha(1.)
fig.canvas.draw()
My question is, is there a workaround that could allow me to do event picking on an errorbar / other complex legend??