matplotlib/matplotlib · error · ValueError
Invalid value for 'layout': {layout!r}
Error message
Invalid value for 'layout': {layout!r} What it means
set_layout_engine — reached from Figure(layout=...), plt.figure(layout=...), or fig.set_layout_engine(...) — accepts only the strings 'constrained', 'compressed', 'tight', 'none', None, or a LayoutEngine instance. Any other value falls through the dispatch chain to this ValueError (lib/matplotlib/figure.py:2825).
Source
Thrown at lib/matplotlib/figure.py:2825
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.')
def get_layout_engine(self):
return self._layout_engine
# TODO: I'd like to dynamically add the _repr_html_ method
# to the figure in the right context, but then IPython doesn't
# use it, for some reason.
def _repr_html_(self):
# We can't use "isinstance" here, because then we'd end up importingView on GitHub (pinned to b379c1b69e)
Solutions
- Use one of the exact strings: 'constrained', 'compressed', 'tight', 'none'
- For custom engines pass an instance: fig.set_layout_engine(TightLayoutEngine())
- Normalize config values first: layout = str(layout).strip().lower() and validate against the allowed set
Example fix
// before
fig = plt.figure(layout='constrained ')
// after
layout = 'constrained'
assert layout in {'constrained', 'compressed', 'tight', 'none'}
fig = plt.figure(layout=layout) Defensive patterns
Strategy: validation
Validate before calling
from matplotlib.layout_engine import LayoutEngine
ALLOWED_LAYOUTS = {'constrained', 'compressed', 'tight', 'none'}
def valid_layout(layout):
return layout is None or layout in ALLOWED_LAYOUTS \
or isinstance(layout, LayoutEngine) Type guard
from matplotlib.layout_engine import LayoutEngine
def is_layout_engine(x):
return isinstance(x, LayoutEngine) Prevention
- Normalize config strings: str(layout).strip().lower() before use
- Validate layout against the allowed set at config load time
- Pass engine instances, not classes, for custom engines
When it happens
Trigger: plt.figure(layout='constrained ') with a trailing space; layout='Tight' (wrong case); layout='auto' or 'default' (not real options); passing TightLayoutEngine (the class) instead of TightLayoutEngine().
Common situations: Typos and case errors in user-supplied config; forwarding unvalidated layout values from YAML/JSON settings; version drift where layout names got mangled between releases or docs.
Related errors
- Width and height specified must be non-negative
- argument must be among %s
- Specifying 'loc' is disallowed when any of its corresponding
- Valid values for `prop` are 'colors' or 'sizes'. You supplie
- t_direction must be 'x' or 'y', got {t_direction!r}
AI-assisted analysis of matplotlib/matplotlib@b379c1b69e (2026-08-21).
Data as JSON: /api/errors/f9304ffc82077757.
Report an issue: GitHub.