diff --git a/doc/api/next_api_changes/removals/22081-AL.rst b/doc/api/next_api_changes/removals/22081-AL.rst index 6f971f3df352..b525da4a5542 100644 --- a/doc/api/next_api_changes/removals/22081-AL.rst +++ b/doc/api/next_api_changes/removals/22081-AL.rst @@ -1,7 +1,10 @@ colorbar defaults to stealing space from the mappable's axes rather than the current axes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Pass ``ax=plt.gca()`` to restore the previous behavior. +If the mappable does not have an Axes, then an error will be raised. + +Pass the *cax* or *ax* argument to be explicit about where the colorbar will be +placed. Passing ``ax=plt.gca()`` will restore the previous behavior. Removal of deprecated ``colorbar`` APIs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/lib/matplotlib/figure.py b/lib/matplotlib/figure.py index 3e8f30efcf64..5bbb786984d2 100644 --- a/lib/matplotlib/figure.py +++ b/lib/matplotlib/figure.py @@ -1245,13 +1245,19 @@ def colorbar( """ if ax is None: - ax = getattr(mappable, "axes", self.gca()) + ax = getattr(mappable, "axes", None) if (self.get_layout_engine() is not None and not self.get_layout_engine().colorbar_gridspec): use_gridspec = False # Store the value of gca so that we can set it back later on. 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.') current_ax = self.gca() userax = False if (use_gridspec and isinstance(ax, SubplotBase)): diff --git a/lib/matplotlib/tests/test_colorbar.py b/lib/matplotlib/tests/test_colorbar.py index c1faef435f55..4c52bed46453 100644 --- a/lib/matplotlib/tests/test_colorbar.py +++ b/lib/matplotlib/tests/test_colorbar.py @@ -315,6 +315,14 @@ def test_colorbarbase(): Colorbar(ax, cmap=plt.cm.bone) +def test_parentless_mappable(): + pc = mpl.collections.PatchCollection([], cmap=plt.get_cmap('viridis')) + pc.set_array([]) + + with pytest.raises(ValueError, match='Unable to determine Axes to steal'): + plt.colorbar(pc) + + @image_comparison(['colorbar_closed_patch.png'], remove_text=True) def test_colorbar_closed_patch(): # Remove this line when this test image is regenerated. @@ -675,7 +683,7 @@ def test_colorbar_inverted_ticks(): def test_mappable_no_alpha(): fig, ax = plt.subplots() sm = cm.ScalarMappable(norm=mcolors.Normalize(), cmap='viridis') - fig.colorbar(sm) + fig.colorbar(sm, ax=ax) sm.set_cmap('plasma') plt.draw()