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

ENH: compressed layout #22289

Merged
merged 1 commit into from Jun 10, 2022
Merged

Conversation

jklymak
Copy link
Member

@jklymak jklymak commented Jan 22, 2022

PR Summary

Replaces #20016

We often want a grid of fixed-aspect ratio axes, but constrained_layout and tigt_layout leave large blank spaces between the axes because they only work with the original axes positions, not the aspect-modified versions.

Here I proposed an extension to constrianed_layout that works for simple grids of axes...

Old:

Exampleconstrained

New:

Examplecompressed

Code

import matplotlib.pyplot as plt
import numpy as np

nrows = 2
ncols = 3
for compress in ['constrained', 'compressed']:
    print('compress?', compress)
    fig, axs = plt.subplots( nrows, ncols, figsize=(4,4),
                            layout=compress,
                            sharex=True, sharey=True)
    fig.patch.set_facecolor("0.9")
    #fig.set_constrained_layout_pads(compress=True)

    for i in range(nrows):
        for j in range(ncols):
            ax = axs[i, j]
            ax.set_aspect(1)
            pc = ax.pcolormesh(np.random.randn(30, 30))
    axs[0, 1].set_xlabel('Boooo')
    fig.colorbar(pc, ax=axs)

Failures...

This isn't perfect, and that is why it is not in "constrained_layout" Folks should be able to turn this off... This example isn't terrible, but its not very good either, though

fig, axs = plt.subplot_mosaic([['A', 'B', 'B'], ['C', 'D', 'E']], layout='compressed',
                            sharex=True, sharey=True)
for k in axs:
    axs[k].imshow(X)

ExampleKindaBad

Or:

fig, axs = plt.subplot_mosaic([['A', 'B', 'B'], ['C', 'B', 'B']], layout='compressed',
                            sharex=True, sharey=True, figsize=(3, 7))

Better

PR Checklist

Tests and Styling

  • Has pytest style unit tests (and pytest passes).
  • Is Flake 8 compliant (install flake8-docstrings and run flake8 --docstring-convention=all).

Documentation

  • New features are documented, with examples if plot related.
  • New features have an entry in doc/users/next_whats_new/ (follow instructions in README.rst there).
  • API changes documented in doc/api/next_api_changes/ (follow instructions in README.rst there).
  • Documentation is sphinx and numpydoc compliant (the docs should build without error).

@jklymak jklymak added the topic: geometry manager LayoutEngine, Constrained layout, Tight layout label Jan 22, 2022
@jklymak jklymak added this to the v3.6.0 milestone Jan 22, 2022
@jklymak jklymak marked this pull request as draft January 22, 2022 19:54
@jklymak jklymak marked this pull request as ready for review January 24, 2022 08:35
@@ -205,6 +205,8 @@ def __init__(self, *, h_pad=None, w_pad=None,
hspace=mpl.rcParams['figure.constrained_layout.hspace'])
# set anything that was passed in (None will be ignored):
self.set(w_pad=w_pad, h_pad=h_pad, wspace=wspace, hspace=hspace)
# see CompressedLayoutEngine below...
Copy link
Member

Choose a reason for hiding this comment

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

This comment seems wrong now?

Copy link
Member Author

Choose a reason for hiding this comment

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

Ooops, yes, I decided against needing a subclass here.

Copy link
Member

Choose a reason for hiding this comment

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

Still needs fixing?

lib/matplotlib/figure.py Outdated Show resolved Hide resolved
tutorials/intermediate/constrainedlayout_guide.py Outdated Show resolved Hide resolved
tutorials/intermediate/constrainedlayout_guide.py Outdated Show resolved Hide resolved
tutorials/intermediate/constrainedlayout_guide.py Outdated Show resolved Hide resolved
lib/matplotlib/_constrained_layout.py Outdated Show resolved Hide resolved
lib/matplotlib/_constrained_layout.py Outdated Show resolved Hide resolved
lib/matplotlib/_constrained_layout.py Outdated Show resolved Hide resolved
@jklymak jklymak force-pushed the enh-compress-layout branch 2 times, most recently from dcca890 to 8175f87 Compare March 24, 2022 14:00
lib/matplotlib/_constrained_layout.py Outdated Show resolved Hide resolved
lib/matplotlib/figure.py Outdated Show resolved Hide resolved
lib/matplotlib/layout_engine.py Outdated Show resolved Hide resolved
tutorials/intermediate/constrainedlayout_guide.py Outdated Show resolved Hide resolved
tutorials/intermediate/constrainedlayout_guide.py Outdated Show resolved Hide resolved
tutorials/intermediate/constrainedlayout_guide.py Outdated Show resolved Hide resolved
tutorials/intermediate/constrainedlayout_guide.py Outdated Show resolved Hide resolved
tutorials/intermediate/constrainedlayout_guide.py Outdated Show resolved Hide resolved
tutorials/intermediate/constrainedlayout_guide.py Outdated Show resolved Hide resolved
@jklymak jklymak force-pushed the enh-compress-layout branch 2 times, most recently from ead8ac7 to e303fbb Compare May 16, 2022 08:22
@@ -205,6 +205,8 @@ def __init__(self, *, h_pad=None, w_pad=None,
hspace=mpl.rcParams['figure.constrained_layout.hspace'])
# set anything that was passed in (None will be ignored):
self.set(w_pad=w_pad, h_pad=h_pad, wspace=wspace, hspace=hspace)
# see CompressedLayoutEngine below...
Copy link
Member

Choose a reason for hiding this comment

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

Still needs fixing?

tutorials/intermediate/constrainedlayout_guide.py Outdated Show resolved Hide resolved
tutorials/intermediate/constrainedlayout_guide.py Outdated Show resolved Hide resolved
tutorials/intermediate/constrainedlayout_guide.py Outdated Show resolved Hide resolved
tutorials/intermediate/constrainedlayout_guide.py Outdated Show resolved Hide resolved
lib/matplotlib/_constrained_layout.py Outdated Show resolved Hide resolved
lib/matplotlib/_constrained_layout.py Outdated Show resolved Hide resolved
Comment on lines +474 to +484
fig, axs = plt.subplots(2, 2, figsize=(5, 3),
sharex=True, sharey=True, layout='compressed')
for ax in axs.flat:
ax.imshow(arr)
fig.suptitle("fixed-aspect plots, layout='compressed'")
Copy link
Member

Choose a reason for hiding this comment

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

This seems to look the same as the constrained version?

Copy link
Member Author

Choose a reason for hiding this comment

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

Agreed, https://output.circle-artifacts.com/output/job/4eee1b1a-1268-4881-8d21-61000c011c8e/artifacts/0/doc/build/html/tutorials/intermediate/constrainedlayout_guide.html#grids-of-fixed-aspect-ratio-axes-compressed-layout

but I have no idea what is happening here. This example works fine manually, just using Agg, etc. I'm flummoxed why the sphinx version doesn't work...

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed in newest version - there was some weird interactions between the rcParam and subsequent calls. maybe worth chasing down, but I could not reproduce without sphinx-gallery, so I guess sphinx-galery is using some weird rcParam contexts?

Copy link
Member Author

Choose a reason for hiding this comment

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

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 the context remains the same through a single file.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, but even if I change the rcParam in a normal script, and then specify the kwarg, compress works fine. But in sphinx- gallery it has this weird problem.

@jklymak jklymak marked this pull request as draft May 28, 2022 17:56
@jklymak jklymak marked this pull request as ready for review May 31, 2022 12:45
tutorials/intermediate/constrainedlayout_guide.py Outdated Show resolved Hide resolved
Comment on lines +474 to +484
fig, axs = plt.subplots(2, 2, figsize=(5, 3),
sharex=True, sharey=True, layout='compressed')
for ax in axs.flat:
ax.imshow(arr)
fig.suptitle("fixed-aspect plots, layout='compressed'")
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 the context remains the same through a single file.

lib/matplotlib/_constrained_layout.py Outdated Show resolved Hide resolved
@@ -84,10 +85,13 @@ def do_constrained_layout(fig, h_pad, w_pad,
A value of 0.2 for a three-column layout would have a space
of 0.1 of the figure width between each column.
If h/wspace < h/w_pad, then the pads are used instead.

Copy link
Contributor

Choose a reason for hiding this comment

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

For consistency with above, this empty line should be here (and one added after the rect description) or all above also removed.

Copy link
Member Author

Choose a reason for hiding this comment

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

Sure, though this is private, so never rendered in the docs ;-)

Adds compress=True to compressed layout engine.  Works for compact
axes grids.
@jklymak
Copy link
Member Author

jklymak commented Jun 10, 2022

I've marked merge with single review. This is pretty stand alone, so it shouldn't break anyone. However, happy to get a second review. I'll merge by next Friday if it doesn't attract one.

@timhoffm timhoffm merged commit b396481 into matplotlib:main Jun 10, 2022
@jklymak
Copy link
Member Author

jklymak commented Jun 10, 2022

Thanks everyone for your work on this!

@timhoffm
Copy link
Member

Thanks everyone for your work on this!

Thanks for creating this! 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: geometry manager LayoutEngine, Constrained layout, Tight layout
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants