3

So I've found this code: https://matplotlib.org/examples/event_handling/legend_picking.html. And I'm trying to make it work for data points instead of lines. So I thought I just change the marker in 'o', but that doesn't seem to work. Also I want to use this in an animation, so that I can decide if I want to follow a datapoint or not. In the end I want to have 10 clickable legend entries.

What I'm trying to do is to just put a marker in the line1, and line2, code:

import numpy as np
import matplotlib.pyplot as plt

t = np.arange(0.0, 0.2, 0.1)
y1 = 2*np.sin(2*np.pi*t)
y2 = 4*np.sin(2*np.pi*2*t)

fig, ax = plt.subplots()
ax.set_title('Click on legend line to toggle line on/off')
line1, = ax.plot(t, y1, ls='None', marker='o', color='red', label='1 HZ')
line2, = ax.plot(t, y2, ls='None', marker='o', color='blue', label='2 HZ')
leg = ax.legend(loc='upper left', fancybox=True, shadow=True)
leg.get_frame().set_alpha(0.4)

# we will set up a dict mapping legend line to orig line, and enable
# picking on the legend line
lines = [line1, line2]
lined = dict()
print(lined)

for legline, origline in zip(leg.get_lines(), lines):
    legline.set_picker(5)  # 5 pts tolerance
    lined[legline] = origline

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 = not origline.get_visible()
    origline.set_visible(vis)
    # Change the alpha on the line in the legend so we can see what lines
    # have been toggled
    if vis:
        legline.set_alpha(1.0)
    else:
        legline.set_alpha(0.2)
    fig.canvas.draw()

fig.canvas.mpl_connect('pick_event', onpick)

plt.show()

Thanks for looking at my problem!

1 Answers1

5

not sure if you're still looking for an answer to this, but I wanted the same thing and this is how I tweaked the code you linked to:

"""
Enable picking on the legend to toggle the original line on and off
"""
import numpy as np
import matplotlib.pyplot as plt

t = np.arange(0.0, 0.2, 0.02)
y1 = 2*np.sin(2*np.pi*t)
y2 = 4*np.sin(2*np.pi*2*t)

fig, ax = plt.subplots()
ax.set_title('Click on legend line to toggle line on/off')
line1leg, = ax.plot(0, 0, lw=2, c='r', label='1 HZ')
line2leg, = ax.plot(0, 0, lw=2, c='b', label='2 HZ')
line1, = ax.plot(t, y1, 'ro', lw=0, label='_nolegend_')
line2, = ax.plot(t, y2, 'bo', lw=0, label='_nolegend_')
leg = ax.legend(fancybox=True, shadow=True)
leg.get_frame().set_alpha(0.4)


# we will set up a dict mapping legend line to orig line, and enable
# picking on the legend line
lines = [line1, line2]
lined = dict()
for legline, origline in zip(leg.get_lines(), lines):
    legline.set_picker(5)  # 5 pts tolerance
    lined[legline] = origline


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 = not origline.get_visible()
    origline.set_visible(vis)
    # Change the alpha on the line in the legend so we can see what lines
    # have been toggled
    #if not vis:
    #    legline.set_alpha(2)
    #    legline.set_marker('^')
    #else:
    #    legline.set_linewidth(3)
    #    legline.set_marker('<')
    if vis:
        legline.set_alpha(1.0)
    else:
        legline.set_alpha(0.2)
    fig.canvas.draw()

fig.canvas.mpl_connect('pick_event', onpick)

plt.show()

It's essentially a cheat, but I found that if I added markers to the plot I couldn't make changes to the marker that appeared in the legend. So we plot the data once as a line, giving it only the point (0,0), then plot the data again as with markers and no line. Then we can continue on and set the legend line transparency to coincide with toggling the plot markers on/off.

user7828298
  • 95
  • 2
  • 7