matplotlib/matplotlib · error · ValueError
n_axes must be positive and not larger than nrows*ncols
Error message
n_axes must be positive and not larger than nrows*ncols
What it means
When constructing `ImageGrid`/`Grid` (mpl_toolkits.axes_grid1.axes_grid) with an explicit `n_axes`, the value must satisfy 0 < n_axes <= nrows*ncols from the `nrows_ncols` pair. Zero, negative values, or values larger than the grid capacity raise ValueError. Omitting n_axes entirely defaults it to exactly nrows*ncols and never triggers this error.
Source
Thrown at lib/mpl_toolkits/axes_grid1/axes_grid.py:124
- "L": All axes on the left column get vertical tick labels;
all axes on the bottom row get horizontal tick labels.
- "1": Only the bottom left axes is labelled.
- "all": All axes are labelled.
- "keep": Do not do anything.
axes_class : subclass of `matplotlib.axes.Axes`, default: `.mpl_axes.Axes`
The type of Axes to create.
aspect : bool, default: False
Whether the axes aspect ratio follows the aspect ratio of the data
limits.
"""
self._nrows, self._ncols = nrows_ncols
if n_axes is None:
n_axes = self._nrows * self._ncols
else:
if not 0 < n_axes <= self._nrows * self._ncols:
raise ValueError(
"n_axes must be positive and not larger than nrows*ncols")
self._horiz_pad_size, self._vert_pad_size = map(
Size.Fixed, np.broadcast_to(axes_pad, 2))
_api.check_in_list(["column", "row"], direction=direction)
self._direction = direction
if axes_class is None:
axes_class = self._defaultAxesClass
elif isinstance(axes_class, (list, tuple)):
cls, kwargs = axes_class
axes_class = functools.partial(cls, **kwargs)
kw = dict(horizontal=[], vertical=[], aspect=aspect)
if isinstance(rect, (Number, SubplotSpec)):
self._divider = SubplotDivider(fig, rect, **kw)
elif len(rect) == 3:View on GitHub (pinned to b379c1b69e)
Solutions
- Omit n_axes so it defaults to nrows*ncols
- Derive the grid from the data: nrows_ncols sized so rows*cols >= n_axes
- If you pass n_axes explicitly, assert 0 < n_axes <= nrows*ncols first
- For 'all axes' semantics pass n_axes=nrows*ncols or None
Example fix
# before grid = ImageGrid(fig, 111, nrows_ncols=(2, 2), n_axes=len(images)) # len=5 fails # after n = len(images) grid = ImageGrid(fig, 111, nrows_ncols=(2, (n + 1) // 2), n_axes=n)
Defensive patterns
Strategy: validation
Validate before calling
rows, cols = nrows_ncols
if n_axes is not None and not 0 < n_axes <= rows * cols:
nrows_ncols = (max(1, (n_axes + cols - 1) // cols), cols)
grid = ImageGrid(fig, 111, nrows_ncols=nrows_ncols, n_axes=n_axes) Type guard
def grid_holds(nrows_ncols, n_axes):
rows, cols = nrows_ncols
return n_axes is None or 0 < n_axes <= rows * cols Try / catch
try:
grid = ImageGrid(fig, 111, nrows_ncols=nrows_ncols, n_axes=n_axes)
except ValueError:
grid = ImageGrid(fig, 111, nrows_ncols=nrows_ncols) # default: all cells Prevention
- Derive nrows_ncols from the data length instead of hardcoding both
- Prefer omitting n_axes when you want the full grid
- Assert 0 < n_axes <= rows*cols when both come from separate sources
When it happens
Trigger: ImageGrid(fig, rect, nrows_ncols=(2, 2), n_axes=0); n_axes=5 with nrows_ncols=(2, 2); n_axes computed as len(images) where images outgrew the configured grid; n_axes=-1 intended to mean 'all'.
Common situations: Parameterizing grid size and image count independently in a plotting function so they drift apart; passing n_axes=len(data) while nrows_ncols comes from a config file; assuming n_axes=0 or None disables the check (None does skip it; 0 does not).
Related errors
- Incorrect rect format
- ref_ax must be set when aspect='axes'
- Unknown format
- linestyles and positions are unequal sized sequences
- 'facecolor' or 'color' argument must be a valid color or seq
AI-assisted analysis of matplotlib/matplotlib@b379c1b69e (2026-08-21).
Data as JSON: /api/errors/d0bc26ff576f6b59.
Report an issue: GitHub.