-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
[Bug]: .contains for some artists does not check for visibility #23875
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
Comments
Definitely agree that is something we need to fix, however I am not convinced that putting the check in Instead, I think a better place to fix this is in matplotlib/lib/matplotlib/artist.py Lines 513 to 525 in 9f17f3f
contains should do.
|
Thanks for the quick reply. From my limited understanding, the pick_event mechanism might be the 'new' nicer way of implementing these interactive elements, but one can also still use So seems to me it would be better to unify this in the contains methods directly (or indeed default_contains if there are not other issues with that). The case of having something set as visible but in practice invisible due to the color/alpha is one interesting thing I didn't think of. |
Oh, 🐑 I did not read carefully enough and thought you were already using I see the argument If contains uniformly did not check visibility, then it is up to the client to do the filtering. Effectively changing your
which is clear about your intentions and I do not think too much more verbose. Another advantage of doing this is that it will work with all versions of Matplotlib independent of where contains lands! On the other hand, if Adding a flag to contains is also an option, but I think a poor one. It would be fewer characters, but not actually any simpler than having the client call When thinking about API choices I tend to consider what the choice will prevent at least as strongly as what it will enable (and the cost to the user of working around an incorrect assumption or the library developers part). On balance, I am still leaning towards
|
Agreed. |
Artists all have a pickable state separate from visible. We could either use that, or add another state. |
Ok well from the discussion it seems like it makes sense from a design point of view if
However, I would caution that if there is an API change that makes point collections, text items etc now no stop checking for visibility then there is a potential to break existing code, and in a way that potentially seems intermittent and is hard to debug. So I think if going that route there should at least in the interim be a warning printed whenever the new behavior occurs, i.e. when a text item's I have to say that while in hindsight the issue is quite simple, in my case finding the bug in my application is probably somewhere among the most difficult bugs I have fixed. Mostly because it occurred so infrequently, only when a user happened to click in exactly the right small area. And it just didn't occur to me that it would be possible to select some types of invisible items, given testing with (more numerous) hidden scatter points not having any issue. |
The pickable state can also be a callable so toggling it can be a bit annoying. I'm also not convinced that more state would be clearer. @rdgraham Sorry if this did not go quite the way you hoped initially! I think one of the things that came out of this discussion is that we may have never actually had a discussion about this which is how we got to the inconsistent state. Definitely agree that when we make a decision one way or the other we should make it clear in the documentation. I also very much agree that the changing the behavior of
seems easier to explain and document than
It seems the worst bugs are not glaring problems, but mostly innocuous / locally sensible behaviors that interact in pathological ways! |
Bug summary
I recently managed to find the source of a long-standing bug in my application that was quite tricky to find.
It turned out to be a consequence of the
contains
method of a line returningtrue
even when the line was set to not visible at the time. Although from what I can see in the documentation there is nothing prohibiting this, I think almost everyone would wantcontains
to return false for objects which have been plotted and set to invisible.Moreover, a non-exhaustive look through the code shows that there are class-specific checks in place for visibility for some objects, but not others. Specifically, the following do not have checks:
But these ones do (though not explicitly documented.)
It seems like a fix might put the check for visibility in the
_default_contains
method ofArtist
. This is called by the child implementations, but as of now seems to provide only a bail-out if the event is outside the figure canvas. Although I guess maybe it was done that way if there are some specific exceptions where you would actually wantcontains
to return true (maybe bounding boxes or more abstract things not plotted directly).Code for reproduction
Actual outcome
It is possible to click anywhere near the invisible line at y=1 and see click registered message.
However, clicking at [0,0], the location of an invisible scatter point does not show a point clicked message (expected behavior).
Expected outcome
Clicking anywhere y=1 should not generate a line click message --- just as clicking at 0,0 does not generate a point clicked message.
Additional information
No response
Operating system
Arch linux, Linux mint, Windows
Matplotlib Version
3.5.0
Matplotlib Backend
qt
Python version
3.9.9
Jupyter version
No response
Installation
No response
The text was updated successfully, but these errors were encountered: