I have to plot several data sets in one plot. It is useful to be able to highlight one or more of the plots in order to compare them. For this, I toggle the line style of th
If you monkey patch Artist.pick with the following:
matplotlib.artist.Artist.orig_pick = matplotlib.artist.Artist.pick
def nu_pick(self, me):
print self
matplotlib.artist.Artist.orig_pick(self, me)
matplotlib.artist.Artist.pick = nu_pick
You can look at how the artists recurse on a pick event. (Each Artist object calls pick on it's self and then on all of it's children). For reasons I don't understand, there are two copies of each line in the drawing area of the legend (and it behaves differently when it is inside and outside).
A way-hacky solution is to just count how many times the leglines have been hit, and only toggle on the odd ones:
import pylab
import numpy
# Create data for plotting
t = numpy.linspace(0, 1.0, 100)
a = numpy.sin(2*numpy.pi*t)
# Set up figure
fig = pylab.figure()
ax = pylab.subplot(111)
# Plot figures
lines = []
for i in range(5):
line = ax.plot(t, (i+1)*a, linestyle=':', picker=5, label='line%d'%(i+1))
lines.append(line[0]) # Save plot lines
# Create legend
leg = ax.legend(bbox_to_anchor=(1.01, 1), loc=2) # Does not work as expected
#leg = ax.legend() # Works!!
# Get legend lines
leglines = leg.get_lines()
# Set event for legend lines
for line in leglines:
line.set_picker(5)
# Create a 2 way mapping between legend lines <-> plot lines
line2leg = dict(zip(lines+leglines, leglines+lines))
count_dict = dict((l, 0) for l in lines )
# Define event function
def onpick(event):
thisline = event.artist
print event
print thisline
if thisline in lines:
print 'lines'
count_dict[thisline] = 0
elif thisline in leglines:
print 'leglines'
thisline = line2leg[thisline]
count_dict[thisline] += 1
print 'added'
if (count_dict[thisline] % 2) == 1:
print count_dict[thisline]
return
print 'tested'
if thisline.get_linestyle()==':':
print ": -> -" # For debugging
thisline.set_linestyle('-')
line2leg[thisline].set_linestyle('-')
else:
print "- -> :" # For debugging
thisline.set_linestyle(':')
line2leg[thisline].set_linestyle(':')
fig.canvas.draw()
# connect event function
fig.canvas.mpl_connect('pick_event', onpick)
pylab.show()
(I left all my de-bugging statements in).
Pretty sure this is a bug, if you don't want to create an issue on github I will.