FIX: add subplot_mosaic axes in the order the user gave them to us#19964
FIX: add subplot_mosaic axes in the order the user gave them to us#19964QuLogic merged 3 commits intomatplotlib:masterfrom
Conversation
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
|
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 |
There was a problem hiding this comment.
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"], | ||
| ["."]]]]] | ||
| ] |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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!).
There was a problem hiding this comment.
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!
There was a problem hiding this comment.
Fair, but that seems much harder to document than "the order is left-to-right and top-down"
jklymak
left a comment
There was a problem hiding this comment.
Despite my suggestions, I'll approve. Feel free to merge if you want it off your plate; it is very clever!
…er the user gave them to us
…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)
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
pytestpasses).flake8on changed files to check).flake8-docstringsand runflake8 --docstring-convention=all).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.