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? Legend Picking Not Working on Marker #18391

Closed
Scoodood opened this issue Sep 1, 2020 · 3 comments
Closed

Bug? Legend Picking Not Working on Marker #18391

Scoodood opened this issue Sep 1, 2020 · 3 comments
Labels
Milestone

Comments

@Scoodood
Copy link

Scoodood commented Sep 1, 2020

I am trying to create legend that can toggle the visibility of each drawn object. Here is my code. It works on the line legend, but clicking on the dot legend object doesn't toggle the drawn object. In contrast, clicking outside the dot legend object will toggle the drawn object. This is counter-intuitive from the use perspective. Does anyone has any workaround to this issue?

import numpy as np
import matplotlib.pyplot as plt


fig = plt.figure()
ax = fig.add_subplot(111)
y = np.random.random(size=50)
x = np.random.choice(np.arange(len(y)), 10, replace=False)
line, = ax.plot(y, '-', label='line')
dot, = ax.plot(x, y[x], 'o', label='dot')
legend = ax.legend()

line_leg, dot_leg = legend.get_lines()
line_leg.set_picker(True)
line_leg.set_pickradius(5)
dot_leg.set_picker(True)
dot_leg.set_pickradius(5)

pickables = {}
pickables[line_leg] = line
pickables[dot_leg] = dot

def on_pick(event):
    leg = event.artist
    visible = leg.get_visible()
    visible = not visible
    pickables[leg].set_visible(visible)
    leg.set_visible(visible)
    fig.canvas.draw()
    
plt.connect('pick_event', on_pick)
plt.show()

out

@Scoodood Scoodood added the Community support Users in need of help. label Sep 1, 2020
@QuLogic
Copy link
Member

QuLogic commented Sep 2, 2020

The problem is that when the legend creates the handles for a Line2D, it actually creates two things, one for the line and one for the marker (I assume to handle the numpoints option). However, for some reason, with any handle consisting of multiple artists, legend only ever returns the first thing. So you've only enable picking on the line part (which is invisible here) and the marker is above that without picking enabled.

I guess what is needed is a "MultiArtist" which could encapsulate the line + marker, draw both, and forward any properties to the latter. I'm not sure if there is any workaround at this time.

@anntzer
Copy link
Contributor

anntzer commented Sep 2, 2020

perhaps see #11358?

@Scoodood
Copy link
Author

Scoodood commented Sep 2, 2020

I found a small trick from stack-overflow. Setting the pick-radius of the dot_legend to 15 solve this problem.

dot_leg.set_pickradius(15)

Now I am wondering which object is on top, line or marker? Why it didn't work at pick-radius = 5.

If the marker is not pickable and the invisible line is always sit above the marker, then why it didn't work at pick-radius = 5?

In contrast, if the marker is above the invisible line, how come a bigger pick radius make it works? I thought the pick-radius only affect the line, but we shouldn't be able to pick the line because it's covered by the marker, right? In this case however, clicking at the center of the marker actually works at pick-radius = 15.

🤔 Any hints on how it work? Really hope that I don't have to study the source code to find out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants