Skip to content

tight layout kwargs have no effect if rc autolayout setting is set (MPL 1.5.3) #7805

Closed

Description

@andim

Bug report

Bug summary

kwargs passed to tight layout do not have an effect if rc the figure.autolayout setting is set

Code for reproduction

No padding is inserted in the following example if figure.autolayout is set to True in the rc

import matplotlib.pyplot as plt
fig, axes = plt.subplots(ncols=2)
fig.tight_layout(w_pad=10)

Matplotlib version

Tested with a conda installed Matplotlib 1.5.3 on Ubuntu Linux.

Activity

  1. added this to the milestone on Jan 12, 2017
  2. modified the milestones: , on May 3, 2017
  3. modified the milestones: , on Oct 9, 2017
  4. github-actions commented on Apr 5, 2023

    @github-actions

    This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!

  5. tacaswell commented on Apr 5, 2023

    @tacaswell
    Member

    This is still a bug. The source of this bug is definitely different than it was before (as we have radically re-done this code).

    The issue is that:

    • tight layout tries to run a one-off layout and then un-set the layout manager to make it "stick"
    • if None is passed to fig.set_layout_manager it falls back to doing what the rcparams say
    • that re-installs a new TightLayout engine with the default parameters

    I think the fix is to make the "unset layout manager" more robust.

  6. added
    🌱 Good first issueOpen a pull request against these issues if there are no active ones!
    Difficulty: Mediumhttps://matplotlib.org/devdocs/devel/contribute.html#good-first-issues
    on Apr 5, 2023
  7. tacaswell commented on Apr 5, 2023

    @tacaswell
    Member

    def set_layout_engine(self, layout=None, **kwargs):
    """
    Set the layout engine for this figure.
    Parameters
    ----------
    layout: {'constrained', 'compressed', 'tight', 'none'} or \
    `LayoutEngine` or None
    - 'constrained' will use `~.ConstrainedLayoutEngine`
    - 'compressed' will also use `~.ConstrainedLayoutEngine`, but with
    a correction that attempts to make a good layout for fixed-aspect
    ratio Axes.
    - 'tight' uses `~.TightLayoutEngine`
    - 'none' removes layout engine.
    If `None`, the behavior is controlled by :rc:`figure.autolayout`
    (which if `True` behaves as if 'tight' was passed) and
    :rc:`figure.constrained_layout.use` (which if `True` behaves as if
    'constrained' was passed). If both are `True`,
    :rc:`figure.autolayout` takes priority.
    Users and libraries can define their own layout engines and pass
    the instance directly as well.
    kwargs: dict
    The keyword arguments are passed to the layout engine to set things
    like padding and margin sizes. Only used if *layout* is a string.
    """
    if layout is None:
    if mpl.rcParams['figure.autolayout']:
    layout = 'tight'
    elif mpl.rcParams['figure.constrained_layout.use']:
    layout = 'constrained'
    else:
    self._layout_engine = None
    return
    if layout == 'tight':
    new_layout_engine = TightLayoutEngine(**kwargs)
    elif layout == 'constrained':
    new_layout_engine = ConstrainedLayoutEngine(**kwargs)
    elif layout == 'compressed':
    new_layout_engine = ConstrainedLayoutEngine(compress=True,
    **kwargs)
    elif layout == 'none':
    if self._layout_engine is not None:
    new_layout_engine = PlaceHolderLayoutEngine(
    self._layout_engine.adjust_compatible,
    self._layout_engine.colorbar_gridspec
    )
    else:
    new_layout_engine = None
    elif isinstance(layout, LayoutEngine):
    new_layout_engine = layout
    else:
    raise ValueError(f"Invalid value for 'layout': {layout!r}")
    if self._check_layout_engines_compat(self._layout_engine,
    new_layout_engine):
    self._layout_engine = new_layout_engine
    else:
    raise RuntimeError('Colorbar layout of new layout engine not '
    'compatible with old engine, and a colorbar '
    'has been created. Engine not changed.')

    and

    finally:
    self.set_layout_engine(None)

    are the badly interacting bits of code.

    I think we need a (private) flag to say "make it None, ignore rcparams" (or use rccontext in the finally?).

  8. rcomer commented on Apr 5, 2023

    @rcomer
    Member

    I haven’t followed this whole thread, but if we want to not have a layout engine we can pass set_layout_engine("none").

  9. added
    keepItems to be ignored by the “Stale” Github Action
    and removed
    status: inactiveMarked by the “Stale” Github Action
    on Apr 5, 2023
  10. tacaswell commented on Apr 5, 2023

    @tacaswell
    Member

    Ah, then using 'none' is probably the right thing to do.

  11. removed
    Difficulty: Mediumhttps://matplotlib.org/devdocs/devel/contribute.html#good-first-issues
    🌱 Good first issueOpen a pull request against these issues if there are no active ones!
    on Apr 5, 2023
  12. added a commit that references this issue on Apr 5, 2023
    009415f
  13. added a commit that references this issue on Apr 17, 2023
    40350ad
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    keepItems to be ignored by the “Stale” Github Action

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions