Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

FIX: remove redundant _make_twin_axes from _subplots#21413

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Draft
jklymak wants to merge3 commits intomatplotlib:main
base:main
Choose a base branch
Loading
fromjklymak:fix-twin-axes

Conversation

jklymak
Copy link
Member

@jklymakjklymak commentedOct 21, 2021
edited
Loading

PR Summary

Closes#21409

For some reason we defined_make_twin_axes twice, and the_subplots version doesn't track movement of the original axes.

EDIT:

OK, the_base_make_twin_axes used an axes_locator to position the twin. The_subplots version just gave the twin asubplotspec and used that for positioning.

In#21409, the user was doing

fig, ax = plt.subplots()ax.set_position([0.5, 0.5, 1, 1])ax2 = ax.twinx()

and the twinax2 was put in the subplotspec position rather than the new position of the parent.

The change here is to always have the twin located by the parent, regardless of how the parent was created. I think that is correct, but I guess its debatable whether we want to change this, or if we want to just tell the user to create the original axes without the subplotspec mechanism. (ie. w/fig.add_axes([0.5, 0.5, 1, 1]))

In either case, this isn't urgent for 3.5.2, so I've moved to 3.6

PR Checklist

  • Has pytest style unit tests (andpytest passes).
  • IsFlake 8 compliant (runflake8 on changed files to check).
  • New features are documented, with examples if plot related.
  • Documentation is sphinx and numpydoc compliant (the docs shouldbuild without error).
  • Conforms to Matplotlib style conventions (installflake8-docstrings and runflake8 --docstring-convention=all).
  • New features have an entry indoc/users/next_whats_new/ (follow instructions in README.rst there).
  • API changes documented indoc/api/next_api_changes/ (follow instructions in README.rst there).

@jklymakjklymak marked this pull request as draftOctober 21, 2021 09:22
@jklymakjklymak added this to thev3.5.1 milestoneOct 21, 2021
@jklymakjklymak marked this pull request as ready for reviewOctober 21, 2021 09:49
@jklymakjklymak marked this pull request as draftOctober 21, 2021 12:57
@QuLogicQuLogic modified the milestones:v3.5.1,v3.5.2Dec 10, 2021
@jklymakjklymak modified the milestones:v3.5.2,v3.6.0Apr 1, 2022
@jklymak
Copy link
MemberAuthor

OK, so now this fails if you try an applytight_layout because the twin axes is locatable, and not a subplot.

One method is to make this axes a child of the parent, and then it won't appear in the axes list for the figure. That, however, comes with z-order changes. Currently ax2 is drawnafter the parent, because it was added after. If we make it a child it can be drawn before some artists in the parent.

@QuLogic
Copy link
Member

If we make it a child it can be drawn before some artists in the parent.

Interestingly, I think that is sometimes something people want? At least when using pickers and stuff. But it would likely be a breaking change to modify the order.

@jklymak
Copy link
MemberAuthor

If we make it a child it can be drawn before some artists in the parent.

Interestingly, I think that is sometimes something people want? At least when using pickers and stuff. But it would likely be a breaking change to modify the order.

For sure, I think people want more control over where the twin is relative to the parent. However, it may also break a lot of people, and I'm not clear how we deprecate it in an obvious way.

@anntzer
Copy link
Contributor

OK, so now this fails if you try an apply tight_layout because the twin axes is locatable, and not a subplot.

Perhaps a solution would be to make tight_layout autoignore any axes that have an axes_locator set? (after all those probably have their own idea of "where they want to go".) Or a safer approach would be to add another flag "ignored_by_layout_engine" and set that flag explicitly for twins (perhaps this can be made private, as this should mostly only affect twins, which are not child axes due to historical causality).

jklymak reacted with thumbs up emoji

@jklymak
Copy link
MemberAuthor

make tight_layout autoignore any axes that have an axes_locator

Well, that doesn't work because we allow the contents of the twin to be included in the extent of the parent. It would be nice to just make the twin a child of the parent, but again that has draw order implications.

I think that this new version works ok - it just adds an extra check and allows the child twin to take its parent subplot spec.

I feel that twins were somewhat questionably defined as peers at some point, whereas life would be easier if one was the parent and the other the child.

if axes_or_locator is None:
axes_or_locator = ax
elif hasattr(ax, '_twinned_axes'):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The hasattr check is unnecessary, as it's a class variable.

Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Oh I see. Well, this fix here is therefore not very good logic. Making the twinned axes siblings is problematic for the original issue - if we move one of the twins, the other twin is supposed to come along. But that implies one of the twins is the parent and one the child.

I guess the redundant_make_twin_axes should remain for the two cases, and likely what needs to change isset_postiion to also change the position of any twins....

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

if we move one of the twins, the other twin is supposed to come along

But does it even make sense to call set_position on an axes that has an axes_locator set? both are basically trying to force the axes' position. Perhaps e.g. set_position could check if an axes_locator exists and ask the user to explicitly callset_axes_locator(None) first if they really want the axes to go here and nowhere else? In that case, for twin axes, the correct way to set their position would be to set the "parent" axes' position, not the child one (which seems correct?) (Yes, I know, it's not a "parent-child" relationship in the usual sense.)

Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Sure, OK, lets try this. If an axes has a locator, but it is a twin, see if the twin has a locator; if not, and it has a subplotspec, use the subplotspec for tight layout. This all seems a little more convoluted than it should be, but....

@jklymakjklymak mentioned this pull requestApr 10, 2022
6 tasks
@QuLogicQuLogic modified the milestones:v3.6.0,v3.7.0Jul 5, 2022
@jklymakjklymak removed this from thev3.7.0 milestoneDec 15, 2022
@jklymakjklymak added this to thefuture releases milestoneDec 15, 2022
@anntzer
Copy link
Contributor

@jklymak I stumbled upon the idea of turning twin axes into child axes as well, and likewise ran into the draw-ordering problem. However, I think this can be solved just be setting a high enough zorder on the twin, so that it gets drawn last? (This means one can break the zordering by inserting artists with custom zorders even higher, but I think we can live with that, or if we want to be super careful that's something we can explicitly detect and warn about during the transition period.)
Doing a warning for people looking for the twin in the figure.axes list and not finding it there is going to be trickier; we may need to decide whether that's something we can just live with.

@jklymak
Copy link
MemberAuthor

...or the twin could be a special child of the parent axes that always gets completely drawn either before or after the parent. That would require another list and a bit of logic to determine if it should be drawn first or second (currently I believe it's drawn second).

The original issue was that if the parent was moved and it was created withfig, ax = plt.subplots() it had a different locator method than if the parent was created viafig.add_axes.Another approach is to not allow axes with a subplot spec to be moved, or if they are moved, convert them to non subplot spec axes, either formally or by setting the subplotspec to None or something. It seems it a user manually moves an Axes with a subplotspec they no longer want it to be part of a subplotsepc.

@anntzer
Copy link
Contributor

...or the twin could be a special child of the parent axes that always gets completely drawn either before or after the parent. That would require another list and a bit of logic to determine if it should be drawn first or second (currently I believe it's drawn second).

To be clear, (unless I got that wrong...) currently child axes are completely drawn as a single block within the parent axes children, i.e. if there's

parent axes with

  • line A in parent, zorder=0
  • child axes X, zorder=1
    • line B in child, zorder=-1
    • line C in child, zorder=3
  • line D in parent, zorder=2

then the draw order is ABCD, not BADC: the zorder of B and C are only used within the child axes and are effectively in a different scale from the zorders of A, X, and D (I think). So to achieve the desired effect we just need to make the zorder of the child-shared axes very large and all its subartists will be drawn after all (other) subartists of the parent.

@jklymak
Copy link
MemberAuthor

For sure I agree, zorder is one way to make the child behave. OTOH, I'm suggesting maybe we want to have child axes or some twin axes in a different list just to remove the ambiguity with normal Artist zorder.

@anntzer
Copy link
Contributor

I'm suggesting maybe we want to have child axes or some twin axes in a different list just to remove the ambiguity with normal Artist zorder.

I'm not sure that really helps here? (and anyways that could be added later I guess)
Now that I look at this I see that inset_axes are simply created with zorder=5, I guess that would also work, in practice, for shared axes?

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@anntzeranntzeranntzer left review comments

At least 1 approving review is required to merge this pull request.

Assignees
No one assigned
Projects
None yet
Milestone
future releases
Development

Successfully merging this pull request may close these issues.

[Bug]: twinx and twiny ignores previous set_position
3 participants
@jklymak@QuLogic@anntzer

[8]ページ先頭

©2009-2025 Movatter.jp