SMS
SMS

Reputation: 382

Legend picking - Enable picking on the legend to toggle the original line on and off

I try to reproduce following example, but however I fail. So what I would like to achieve is following: I have mutiple dataframes and these should be plotted individually - For this I already created a UI. I would like to click on the items on within the legend to switch on or off the line. To achieve this I used the following example

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, lw=2, label='1 HZ')
line2, = ax.plot(t, y2, lw=2, 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()
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()

If copy paste this to have two figures (I did this to check my error - since I had an error producing multiple plots) it gives me two figures, but I am not able to click on the legends of both figures, only on the last, here my 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, lw=2, label='1 HZ')
Line2, = ax.plot(t, y2, lw=2, 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()
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()

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, lw=2, label='1 HZ')
line2, = ax.plot(t, y2, lw=2, 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()
for legline, origline in zip(leg.get_lines(), lines):
    legline.set_picker(5)  # 5 pts tolerance
    lined[legline] = origline


def onpick2(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', onpick2)

plt.show()

So basically I just copy pasted it. But it's not working the way I expected it. Anyone any recommendation?

Upvotes: 0

Views: 210

Answers (1)

Diziet Asahi
Diziet Asahi

Reputation: 40727

You are using some variables that have the same name in the first and second figures. The event handling for the first figure is trying to access variables that have been overwritten in creating the second figure, and that's where things fail.

If you make sure you use unique variable names, everything works:

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)

fig1, ax1 = plt.subplots()
ax1.set_title('Click on legend line to toggle line on/off')
Line11, = ax1.plot(t, y1, lw=2, label='1 HZ')
Line12, = ax1.plot(t, y2, lw=2, label='2 HZ')
Leg1 = ax1.legend(loc='upper left', fancybox=True, shadow=True)
Leg1.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
Lines1 = [Line11, Line12]
Lined1 = dict()
for Legline, Origline in zip(Leg1.get_lines(), Lines1):
    Legline.set_picker(5)  # 5 pts tolerance
    Lined1[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 = Lined1[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)
    fig1.canvas.draw()


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

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)

fig2, ax2 = plt.subplots()
ax2.set_title('Click on legend line to toggle line on/off')
line21, = ax2.plot(t, y1, lw=2, label='1 HZ')
line22, = ax2.plot(t, y2, lw=2, label='2 HZ')
leg2 = ax2.legend(loc='upper left', fancybox=True, shadow=True)
leg2.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
lines2 = [line21, line22]
lined2 = dict()
for legline, origline in zip(leg2.get_lines(), lines2):
    legline.set_picker(5)  # 5 pts tolerance
    lined2[legline] = origline


def onpick2(event):
    # on the pick event, find the orig line corresponding to the
    # legend proxy line, and toggle the visibility
    legline = event.artist
    origline = lined2[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)
    fig2.canvas.draw()


fig2.canvas.mpl_connect('pick_event', onpick2)

plt.show()

Upvotes: 1

Related Questions