{"record":{"id":"92e1630de8b54379","repo":"matplotlib/matplotlib","slug":"unable-to-determine-axes-to-steal-space-for-colorb","errorCode":null,"errorMessage":"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.","messagePattern":"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\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"lib/matplotlib/figure.py","lineNumber":1362,"sourceCode":"        the viewers, not Matplotlib.  As a workaround, the colorbar can be\n        rendered with overlapping segments::\n\n            cbar = colorbar()\n            cbar.solids.set_edgecolor(\"face\")\n            draw()\n\n        However, this has negative consequences in other circumstances, e.g.\n        with semi-transparent images (alpha < 1) and colorbar extensions;\n        therefore, this workaround is not used by default (see issue #1188).\n\n        \"\"\"\n\n        if ax is None:\n            ax = getattr(mappable, \"axes\", None)\n\n        if cax is None:\n            if ax is None:\n                raise ValueError(\n                    'Unable to determine Axes to steal space for Colorbar. '\n                    'Either provide the *cax* argument to use as the Axes for '\n                    'the Colorbar, provide the *ax* argument to steal space '\n                    'from it, or add *mappable* to an Axes.')\n            fig = (  # Figure of first Axes; logic copied from make_axes.\n                [*ax.flat] if isinstance(ax, np.ndarray)\n                else [*ax] if np.iterable(ax)\n                else [ax])[0].get_figure(root=False)\n            current_ax = fig.gca()\n            if (fig.get_layout_engine() is not None and\n                    not fig.get_layout_engine().colorbar_gridspec):\n                use_gridspec = False\n            if (use_gridspec\n                    and isinstance(ax, mpl.axes._base._AxesBase)\n                    and ax.get_subplotspec()):\n                cax, kwargs = cbar.make_axes_gridspec(ax, **kwargs)\n            else:\n                cax, kwargs = cbar.make_axes(ax, **kwargs)","sourceCodeStart":1344,"sourceCodeEnd":1380,"githubUrl":"https://github.com/matplotlib/matplotlib/blob/b379c1b69e012b142c0f496a52bcb30513802d72/lib/matplotlib/figure.py#L1344-L1380","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","solutions":["Pass cax= with a dedicated Axes (fig.add_axes(...) or ax.inset_axes(...)) so no space needs to be stolen","Pass ax= (a single Axes or a list of Axes) to steal space from existing axes","If the mappable should belong to a plot, attach it first (im = ax.imshow(...)) and pass that mappable to fig.colorbar","For a standalone colorbar, create the target Axes manually and always use the cax form"],"exampleFix":"// before\nimport matplotlib.pyplot as plt\nfrom matplotlib.cm import ScalarMappable\nfrom matplotlib.colors import Normalize\nfig = plt.figure()\nsm = ScalarMappable(norm=Normalize(0, 1), cmap='viridis')\nfig.colorbar(sm)  # ValueError: Unable to determine Axes to steal space\n\n// after\ncax = fig.add_axes([0.92, 0.15, 0.03, 0.7])\nfig.colorbar(sm, cax=cax)\n# or steal space from an existing axes: fig.colorbar(sm, ax=ax)","handlingStrategy":"validation","validationCode":"# before calling fig.colorbar(mappable)\nif cax is None and ax is None and getattr(mappable, 'axes', None) is None:\n    raise ValueError(\n        'colorbar needs ax= or cax= when the mappable is not attached to an Axes')","typeGuard":null,"tryCatchPattern":"try:\n    fig.colorbar(sm)\nexcept ValueError as e:\n    if 'Unable to determine Axes' not in str(e):\n        raise\n    cax = fig.add_axes([0.92, 0.15, 0.03, 0.7])\n    fig.colorbar(sm, cax=cax)","preventionTips":["Always pass ax= or cax= when the mappable is a bare ScalarMappable","Create the mappable via ax.imshow / ax.pcolormesh so it carries .axes","For multi-axes colorbars pass ax=[ax1, ax2] explicitly"],"tags":["matplotlib","colorbar","axes","scalar-mappable"],"backgroundTag":"colorbar-missing-axes","analyzedSha":"b379c1b69e012b142c0f496a52bcb30513802d72","analyzedAt":"2026-08-21T23:31:55.468Z","schemaVersion":2},"datasetVersion":"2026-08-22T04:17:13.399Z"}