Thanks to visit codestin.com
Credit goes to github.com

Skip to content

FIX: add subplot_mosaic axes in the order the user gave them to us #19964

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

Merged
merged 3 commits into from
Apr 16, 2021

Conversation

tacaswell
Copy link
Member

PR Summary

The order the Axes are added to the Figure (and hence the order they are in
the returned dictionary and fig.axes) is now based on the first time we see the
key if the layout were recursively unraveled as a c-style array.

Closes #19736

PR Checklist

  • Has pytest style unit tests (and pytest passes).
  • Is Flake 8 compliant (run flake8 on changed files to check).
  • Conforms to Matplotlib style conventions (install flake8-docstrings and run flake8 --docstring-convention=all).
  • API changes documented in doc/api/next_api_changes/ (follow instructions in README.rst there).

I don't think this needs an API change note as the order was previously unreliable.

The order the Axes are added to the Figure (and hence the order they are in
the returned dictionary and fig.axes) is now based on the first time we see the
key if the layout were recursively unraveled as a c-style array.

Closes matplotlib#19736
@tacaswell tacaswell added this to the v3.4.2 milestone Apr 15, 2021
@jklymak
Copy link
Member

jklymak commented Apr 15, 2021

I'd need to add a bunch of print statements to properly follow what is going on now. Can you add more comments or refactor in any way to make this easier to follow?

May comeback to refactor the function dispatch to be actually stand-alone
helper functions that we can call rather than being inline code.
# on the 'method' string stashed above to sort out if this
# element is an axes or a nested layout.
if method == 'axes':
slc = arg
Copy link
Member Author

Choose a reason for hiding this comment

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

I went back and forth on if pulling out the bodies of the if and elif into functions and doing

for key in sorted(this_level):
    name, arg, method = this_level[key]
    mapping[method](name, arg)

would be clearer or not.

["F", "G"],
[".", [["H", [["I"],
["."]]]]]
]
Copy link
Member

Choose a reason for hiding this comment

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

OK, I now see why this was such a blister.

Congrats for figuring out how to do this. OTOH, I don't think getting the nested axes in order with the level above is a necessary complication. I personally would expect the order to be something like "AFG BCDE H I" or put another way, I don't think anyone has a need or the right to expect the nested axes to be in any sort of order with respect to axes at the parent level.

i.e. in very quick pseudocode:

for a in name: 
  if axes:
    alist += [make_axes]
for a in name:
  if nested:
    alist += add_children()

We can keep it, and I'm not going to block at all. But I do think making it this clever is making the code less maintainable.

If you keep this way, I would explain this a bit in the comment above so that the reader is expecting considerable complexity.

Copy link
Member

@jklymak jklymak Apr 16, 2021

Choose a reason for hiding this comment

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

Another super simple way to sort would be to do what you did before, and then assign a numerical value to each axes based on its subplot spec. If it is down a level, add the parent subplot spec to the child subplot spec divided by 10, etc. Above you would get

A: 0, B: 1.0, C: 1.1, D: 1.2, E: 1.3, F: 2, G: 3, H: 5.0, I: 6.00

Copy link
Member Author

Choose a reason for hiding this comment

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

Visually these two layouts should produce the same figure (to 0th order, they end up with slightly different spacing due to the way nested gridspecs work):

layout1="""
        AABC
        AADE
        FFGG
        FFGG
        ..HI
        ..H.
        """

layout2 = [
            ["A", [["B", "C"],
                   ["D", "E"]]],
            ["F", "G"],
            [".", [["H", [["I"],
                          ["."]]]]]
        ]


fig1, axd1 = plt.subplot_mosaic(layout1)
fig2, axd2 = plt.subplot_mosaic(layout2)

I think it would be very surprising if changing how the layout is specified changed the order (now that it has been pointed out to me that people care about the order!).

Copy link
Member

Choose a reason for hiding this comment

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

I think it would be very surprising if changing how the layout is specified changed the order

I think it would be surprising if it didn't change the order!

Copy link
Member Author

Choose a reason for hiding this comment

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

Fair, but that seems much harder to document than "the order is left-to-right and top-down"

Copy link
Member

@jklymak jklymak left a comment

Choose a reason for hiding this comment

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

Despite my suggestions, I'll approve. Feel free to merge if you want it off your plate; it is very clever!

@QuLogic QuLogic merged commit 48b7c98 into matplotlib:master Apr 16, 2021
meeseeksmachine pushed a commit to meeseeksmachine/matplotlib that referenced this pull request Apr 16, 2021
@tacaswell tacaswell deleted the fix_mosaic_order branch April 16, 2021 21:44
QuLogic added a commit that referenced this pull request Apr 17, 2021
…964-on-v3.4.x

Backport PR #19964 on branch v3.4.x (FIX: add subplot_mosaic axes in the order the user gave them to us)
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.

subplot_mosaic axes are not added in consistent order
3 participants