Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: Macosx legend picker doesn't work anymore #22760

Closed
samlobe opened this issue Apr 1, 2022 · 4 comments
Closed

[Bug]: Macosx legend picker doesn't work anymore #22760

samlobe opened this issue Apr 1, 2022 · 4 comments
Milestone

Comments

@samlobe
Copy link

samlobe commented Apr 1, 2022

Bug summary

I used to be able to use a legend picker as described in this matplotlib tutorial.
It doesn't work anymore. I bet it was an up

Code for reproduction

import numpy as np
import matplotlib.pyplot as plt


t = np.linspace(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(fancybox=True, shadow=True)

lines = [line1, line2]
lined = {}  # Will map legend lines to original lines.
for legline, origline in zip(leg.get_lines(), lines):
    legline.set_picker(True)  # Enable picking on the legend line.
    lined[legline] = origline


def on_pick(event):
    # On the pick event, find the original line corresponding to the legend
    # proxy line, and toggle its visibility.
    legline = event.artist
    origline = lined[legline]
    visible = not origline.get_visible()
    origline.set_visible(visible)
    # Change the alpha on the line in the legend so we can see what lines
    # have been toggled.
    legline.set_alpha(1.0 if visible else 0.2)
    fig.canvas.draw()

fig.canvas.mpl_connect('pick_event', on_pick)
plt.show()

Actual outcome

It graphs fine, but I can't toggle visibility by clicking the legend.
I've tried executing the code from my Mac Terminal and from an IDE (Spyder) with Python 3.8.12 and matplotlib version 3.5.1.

Expected outcome

I should be able to click and toggle the visibility.

Additional information

Legend picking with this script still works from my other Spyder app, which has python 3.9.2 and matplotlib 3.3.4.

Operating system

macOS Monterey

Matplotlib Version

3.5.1

Matplotlib Backend

MacOSX

Python version

3.8.12

Jupyter version

No response

Installation

conda

@jklymak
Copy link
Member

jklymak commented Apr 1, 2022

Confirmed that this is broken on v3.5.1 with 'macosx'. Note that it works fine for 'qt5agg'. However, running on master this runs fine, so I suspect a recent macOS fix here, maybe @greglucas or @dstansby knows what was fixed. Thanks for the report, however, this should be fixed in v3.6 (unfortunately not in the bug fix release 3.5.2, due out soon)

@jklymak jklymak changed the title [Bug]: legend picker doesn't work anymore [Bug]: Macosx legend picker doesn't work anymore Apr 1, 2022
@greglucas
Copy link
Contributor

I don't see anything immediately obvious in 3.5.x that would cause this looking through the difference.
https://github.com/matplotlib/matplotlib/compare/v3.5.1..v3.4.3

The issue is with requesting a redraw. After clicking to remove the line and then resizing the window, you can see the change did happen it just didn't show up. Additionally, changing fig.canvas.draw() to fig.canvas.draw_idle() in the example code avoids the update failure on 3.5.1, so I'd suggest using that workaround for now if you can. On main, the entire draw/draw_idle event flow was updated to follow the other backends better, but that was a pretty large change that I don't think we want to backport to 3.5.x.

@tacaswell
Copy link
Member

Is the issue that the pick event never fires or that the update is not being reflected? If you resize the window (which unconditionally causes a full redraw because we need a different number of pixels!) do the changes get reflected correctly? If so then I think @greglucas 's explanation of what is wrong / why it works on main is correct. If not, then please put some prints in the callback to make sure the events are actually firing (and if they are not that is very worrying).

@greglucas
Copy link
Contributor

I'm going to close this issue as fixed on main and will be in the upcoming 3.6 release. There is also a reasonable workaround (using draw_idle() instead of draw()) on 3.5 since we aren't backporting the macos fixes to 3.5.x.

@greglucas greglucas added this to the v3.6.0 milestone May 1, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants