matplotlib/matplotlib · error · ValueError

Unable to determine Axes to steal space for Colorbar. Either

Error message

Unable to determine Axes to steal space for Colorbar. Either provide the *cax* argument to use as the Axes for the Colorbar, provide the *ax* argument to steal space from it, or add *mappable* to an Axes.

What it means

Figure.colorbar() must know which Axes to shrink so the colorbar fits. It infers that from the mappable's .axes attribute, or from the explicit ax / cax arguments. A bare ScalarMappable (or any mappable never added to an Axes) has .axes None, so when neither ax nor cax is supplied there is no source of space and matplotlib raises this ValueError (lib/matplotlib/figure.py:1362).

Source

Thrown at lib/matplotlib/figure.py:1362

        the viewers, not Matplotlib.  As a workaround, the colorbar can be
        rendered with overlapping segments::

            cbar = colorbar()
            cbar.solids.set_edgecolor("face")
            draw()

        However, this has negative consequences in other circumstances, e.g.
        with semi-transparent images (alpha < 1) and colorbar extensions;
        therefore, this workaround is not used by default (see issue #1188).

        """

        if ax is None:
            ax = getattr(mappable, "axes", None)

        if cax is None:
            if ax is None:
                raise ValueError(
                    'Unable to determine Axes to steal space for Colorbar. '
                    'Either provide the *cax* argument to use as the Axes for '
                    'the Colorbar, provide the *ax* argument to steal space '
                    'from it, or add *mappable* to an Axes.')
            fig = (  # Figure of first Axes; logic copied from make_axes.
                [*ax.flat] if isinstance(ax, np.ndarray)
                else [*ax] if np.iterable(ax)
                else [ax])[0].get_figure(root=False)
            current_ax = fig.gca()
            if (fig.get_layout_engine() is not None and
                    not fig.get_layout_engine().colorbar_gridspec):
                use_gridspec = False
            if (use_gridspec
                    and isinstance(ax, mpl.axes._base._AxesBase)
                    and ax.get_subplotspec()):
                cax, kwargs = cbar.make_axes_gridspec(ax, **kwargs)
            else:
                cax, kwargs = cbar.make_axes(ax, **kwargs)

View on GitHub (pinned to b379c1b69e)

Solutions

  1. Pass cax= with a dedicated Axes (fig.add_axes(...) or ax.inset_axes(...)) so no space needs to be stolen
  2. Pass ax= (a single Axes or a list of Axes) to steal space from existing axes
  3. If the mappable should belong to a plot, attach it first (im = ax.imshow(...)) and pass that mappable to fig.colorbar
  4. For a standalone colorbar, create the target Axes manually and always use the cax form

Example fix

// before
import matplotlib.pyplot as plt
from matplotlib.cm import ScalarMappable
from matplotlib.colors import Normalize
fig = plt.figure()
sm = ScalarMappable(norm=Normalize(0, 1), cmap='viridis')
fig.colorbar(sm)  # ValueError: Unable to determine Axes to steal space

// after
cax = fig.add_axes([0.92, 0.15, 0.03, 0.7])
fig.colorbar(sm, cax=cax)
# or steal space from an existing axes: fig.colorbar(sm, ax=ax)
Defensive patterns

Strategy: validation

Validate before calling

# before calling fig.colorbar(mappable)
if cax is None and ax is None and getattr(mappable, 'axes', None) is None:
    raise ValueError(
        'colorbar needs ax= or cax= when the mappable is not attached to an Axes')

Try / catch

try:
    fig.colorbar(sm)
except ValueError as e:
    if 'Unable to determine Axes' not in str(e):
        raise
    cax = fig.add_axes([0.92, 0.15, 0.03, 0.7])
    fig.colorbar(sm, cax=cax)

Prevention

When it happens

Trigger: fig.colorbar(ScalarMappable(norm=norm, cmap=cmap)) with no ax= or cax=; plt.colorbar(sm) where sm was created standalone; building the colorbar before the im = ax.imshow(...) call that would attach the mappable to an Axes.

Common situations: Colorbar-only figures built from a norm/cmap pair; refactors that replaced an attached image mappable with a detached ScalarMappable; mappables that live on a different figure than the colorbar; tests assembling Figure objects by hand.

Related errors


AI-assisted analysis of matplotlib/matplotlib@b379c1b69e (2026-08-21). Data as JSON: /api/errors/92e1630de8b54379. Report an issue: GitHub.