From 9753708d3e5edfe0d39d7c70933de0666910c696 Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Mon, 30 Dec 2019 23:34:09 +0100 Subject: [PATCH] Deprecate parameters to colorbar which have no effect. Per changelog entry. I went for a custom helper in colorbar.py rather than a more general one in cbook as this allowed for a nicer message, and making the general helper handle the deprecation would be a bit unwieldy. --- doc/api/next_api_changes/deprecations.rst | 10 ++++ .../contour_demo.py | 4 +- lib/matplotlib/colorbar.py | 52 ++++++++++++------- lib/matplotlib/tests/test_colorbar.py | 8 ++- 4 files changed, 48 insertions(+), 26 deletions(-) diff --git a/doc/api/next_api_changes/deprecations.rst b/doc/api/next_api_changes/deprecations.rst index 9616039e20c7..12c8bbf8857d 100644 --- a/doc/api/next_api_changes/deprecations.rst +++ b/doc/api/next_api_changes/deprecations.rst @@ -96,3 +96,13 @@ colormapping such as ``scatter()`` and ``imshow()`` is deprecated. Inestead of ``norm=LogNorm(), vmin=min_val, vmax=max_val`` pass ``norm=LogNorm(min_val, max_val)``. *vmin* and *vmax* should only be used without setting *norm*. + +Effectless parameters of `.Figure.colorbar` and `matplotlib.colorbar.Colorbar` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The *cmap* and *norm* parameters of `.Figure.colorbar` and +`matplotlib.colorbar.Colorbar` have no effect because they are always +overridden by the mappable's colormap and norm; they are thus deprecated. +Likewise, passing the *alpha*, *boundaries*, *values*, *extend*, or *filled* +parameters with a `.ContourSet` mappable, or the *alpha* parameter with an +`.Artist` mappable, is deprecated, as the mappable would likewise override +them. diff --git a/examples/images_contours_and_fields/contour_demo.py b/examples/images_contours_and_fields/contour_demo.py index f7d1222e563a..763b0789a870 100644 --- a/examples/images_contours_and_fields/contour_demo.py +++ b/examples/images_contours_and_fields/contour_demo.py @@ -82,7 +82,7 @@ im = ax.imshow(Z, interpolation='bilinear', origin='lower', cmap=cm.gray, extent=(-3, 3, -2, 2)) levels = np.arange(-1.2, 1.6, 0.2) -CS = ax.contour(Z, levels, origin='lower', cmap='flag', +CS = ax.contour(Z, levels, origin='lower', cmap='flag', extend='both', linewidths=2, extent=(-3, 3, -2, 2)) # Thicken the zero contour. @@ -93,7 +93,7 @@ inline=1, fmt='%1.1f', fontsize=14) # make a colorbar for the contour lines -CB = fig.colorbar(CS, shrink=0.8, extend='both') +CB = fig.colorbar(CS, shrink=0.8) ax.set_title('Lines with colorbar') diff --git a/lib/matplotlib/colorbar.py b/lib/matplotlib/colorbar.py index afa1dd285216..bad99b4ad411 100644 --- a/lib/matplotlib/colorbar.py +++ b/lib/matplotlib/colorbar.py @@ -1155,6 +1155,19 @@ def remove(self): self.ax.remove() +def _add_disjoint_kwargs(d, **kwargs): + """ + Update dict *d* with entries in *kwargs*, which must be absent from *d*. + """ + for k, v in kwargs.items(): + if k in d: + cbook.warn_deprecated( + "3.3", message=f"The {k!r} parameter to Colorbar has no " + "effect because it is overridden by the mappable; it is " + "deprecated since %(since)s and will be removed %(removal)s.") + d[k] = v + + class Colorbar(ColorbarBase): """ This class connects a `ColorbarBase` to a `~.cm.ScalarMappable` @@ -1165,35 +1178,36 @@ class Colorbar(ColorbarBase): `.Figure.colorbar` or `.pyplot.colorbar` to create a colorbar. """ - def __init__(self, ax, mappable, **kw): + def __init__(self, ax, mappable, **kwargs): # Ensure the given mappable's norm has appropriate vmin and vmax set # even if mappable.draw has not yet been called. if mappable.get_array() is not None: mappable.autoscale_None() self.mappable = mappable - kw['cmap'] = cmap = mappable.cmap - kw['norm'] = mappable.norm + _add_disjoint_kwargs(kwargs, cmap=mappable.cmap, norm=mappable.norm) if isinstance(mappable, contour.ContourSet): - CS = mappable - kw['alpha'] = mappable.get_alpha() - kw['boundaries'] = CS._levels - kw['values'] = CS.cvalues - kw['extend'] = CS.extend - kw.setdefault('ticks', ticker.FixedLocator(CS.levels, nbins=10)) - kw['filled'] = CS.filled - ColorbarBase.__init__(self, ax, **kw) - if not CS.filled: - self.add_lines(CS) + cs = mappable + _add_disjoint_kwargs( + kwargs, + alpha=cs.get_alpha(), + boundaries=cs._levels, + values=cs.cvalues, + extend=cs.extend, + filled=cs.filled, + ) + kwargs.setdefault( + 'ticks', ticker.FixedLocator(cs.levels, nbins=10)) + ColorbarBase.__init__(self, ax, **kwargs) + if not cs.filled: + self.add_lines(cs) else: - if getattr(cmap, 'colorbar_extend', False) is not False: - kw.setdefault('extend', cmap.colorbar_extend) - + if getattr(mappable.cmap, 'colorbar_extend', False) is not False: + kwargs.setdefault('extend', mappable.cmap.colorbar_extend) if isinstance(mappable, martist.Artist): - kw['alpha'] = mappable.get_alpha() - - ColorbarBase.__init__(self, ax, **kw) + _add_disjoint_kwargs(kwargs, alpha=mappable.get_alpha()) + ColorbarBase.__init__(self, ax, **kwargs) def on_mappable_changed(self, mappable): """ diff --git a/lib/matplotlib/tests/test_colorbar.py b/lib/matplotlib/tests/test_colorbar.py index f4440cbd7366..082d0d4ba7ed 100644 --- a/lib/matplotlib/tests/test_colorbar.py +++ b/lib/matplotlib/tests/test_colorbar.py @@ -243,8 +243,7 @@ def test_colorbar_closed_patch(): # because it is matched to the data range in the image and to # the number of colors in the LUT. values = np.linspace(0, 10, 5) - cbar_kw = dict(cmap=cmap, orientation='horizontal', values=values, - ticks=[]) + cbar_kw = dict(orientation='horizontal', values=values, ticks=[]) # The wide line is to show that the closed path is being handled # correctly. See PR #4186. @@ -264,9 +263,8 @@ def test_colorbar_ticks(): Z = X * Y clevs = np.array([-12, -5, 0, 5, 12], dtype=float) colors = ['r', 'g', 'b', 'c'] - cs = ax.contourf(X, Y, Z, clevs, colors=colors) - cbar = fig.colorbar(cs, ax=ax, extend='neither', - orientation='horizontal', ticks=clevs) + cs = ax.contourf(X, Y, Z, clevs, colors=colors, extend='neither') + cbar = fig.colorbar(cs, ax=ax, orientation='horizontal', ticks=clevs) assert len(cbar.ax.xaxis.get_ticklocs()) == len(clevs)