Skip to content

ENH: Switch to constrained layout in figure creation #12024

@larsoner

Description

@larsoner

I've mentioned this a few times in passing (e.g., 1, 2) but thought it deserves its own issue. I've been using plt.subplots(..., constrained_layout=True) for a few years in many use cases and I can't think of a time it produced a bad (or even sub-optimal) result. By comparison, the default tight_layout engine and workflow almost always needs some manual adjustment to use space optimally.

I propose we try switching our plt.subplots and related matplotlib-figure-creation calls to use the constrained layout engine wherever possible, build the doc, and see if it does indeed improve things. In particular I expect it:

  1. Will produce better results more consistently in (nearly?) all cases compared to current code that calls subplots_adjust and tight_layout
  2. Is easy enough for people to get old behavior back by switching the layout engine on their own with fig.set_layout_engine('tight') and/or fig.tight_layout etc.
  3. Will allow us to simplify our code because we won't need to tweak plot margins etc. nearly as much (or at all) anymore, just make minimal decisions (e.g., how much space do I want to reserve for the colorbar?)
  4. By removing all our internal uses of subplots_adjust / tight_layout, if a user passes in their own axes we'll leave them alone rather than tweak the figure properties, which seems like cleaner/nicer behavior. (If a user passes axes it should be up to them to deal with spacing issues however they wish without us messing with the spacing.)

So I expect an overall meaningful aesthetic and maintenance win by going this route. Since we consider aesthetic changes non-breaking I don't think we need a deprecation cycle for this. If we anticipate user backlash, we could add a mne.viz.use/get/set_figure_layout_engine, but I'd assume YAGNI and just have users do fig.set_layout_engine('tight') when they need it.

Bringing this up was inspired by @mscheltienne going this direction a bit already in #12020.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions