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

Fixes legend.get_children() to actually return the real children of #2755

Merged
merged 1 commit into from Feb 1, 2014

Conversation

cimarronm
Copy link
Contributor

legend while not including descendents who are children of other
objects (what would be grandchildren, great grandchildren, etc.)

legend while not including descendents who are children of other
objects (what would be grandchildren, great grandchildren, etc.)
@cimarronm
Copy link
Contributor Author

The main problem here is that legend erroneously (my viewpoint of what a child is) returns not only children but other descendants as well (i.e. grand children, great grand children, etc.). In doing so, one can no longer use the get_children method to build a true traversal tree for objects underneath it.

Thus, functions like the picker in the artist will not behave correctly and end up calling descendants more than once as they attempt to traverse the object tree as you see in the artist code excerpt below. This is what results as seen in the bug for issue #1962.

        # Pick children
        for a in self.get_children():
            # make sure the event happened in the same axes
            ax = getattr(a, 'axes', None)
            if mouseevent.inaxes is None or mouseevent.inaxes == ax:
                # we need to check if mouseevent.inaxes is None
                # because some objects associated with an axes (e.g., a
                # tick label) can be outside the bounding box of the
                # axes and inaxes will be None
                a.pick(mouseevent)

This PR removes descendants from legend.get_children() who are not direct children of the legend itself.

@tacaswell
Copy link
Member

I don't really understand why this works (or more precisely, why it used to work when the legend was inside the axes), but it does.

👍 to merge from me.

@mdboom
Copy link
Member

mdboom commented Jan 27, 2014

Cc: @leejjoon, @pelson as people who have far more experience with the legend code than I. Any ideas why it currently behaves the way it does? I buy @cimarronm's argument that get_children returns more than just its own children, but seemingly it must do that for a reason...?

@pelson
Copy link
Member

pelson commented Jan 27, 2014

In doing so, one can no longer use the get_children method to build a true traversal tree for objects underneath it.

I'm not sure the method (despite its name) is designed for that purpose. @mdboom mentioned the other day that DOM type traversal would be a great addition, but that wouldn't have to be shoe-horned into existing methods necessarily.

All of the above said, I know of no reason why get_children needed to add these non-direct descendants to the list, and in principle, provided it doesn't break anything I'm OK with changing it.

@tacaswell
Copy link
Member

I do wonder how much code gets left in strange states because 'it must be that way for a reason....'

tacaswell added a commit that referenced this pull request Feb 1, 2014
Fixes legend.get_children() to actually return the real children of
@tacaswell tacaswell merged commit db0fbd4 into matplotlib:master Feb 1, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants