Skip to content

Commit

Permalink
FIX: add missing method to ColormapRegistry
Browse files Browse the repository at this point in the history
After putting pending deprecations on `cm.get_cmap` we discovered that
downstream libraries (pandas) were using the deprecated method to normalize
between `None` (to get the default colormap), strings, and Colormap instances.
This adds a method to `ColormapRegistry` to do this normalization.

This can not replace our internal helper due to variations in what exceptions
are raised.

Closes matplotlib#23981
  • Loading branch information
tacaswell authored and melissawm committed Dec 19, 2022
1 parent 8e18b75 commit 283b71d
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 3 deletions.
10 changes: 8 additions & 2 deletions doc/api/prev_api_changes/api_changes_3.6.0/deprecations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,13 @@ In Matplotlib 3.6 we have marked those top level functions as pending
deprecation with the intention of deprecation in Matplotlib 3.7. The following
functions have been marked for pending deprecation:

- ``matplotlib.cm.get_cmap``; use ``matplotlib.colormaps[name]`` instead
- ``matplotlib.cm.get_cmap``; use ``matplotlib.colormaps[name]`` instead if you
have a `str`.

**Added 3.6.1** Use `matplotlib.cm.ColormapRegistry.get_cmap` if you
have a string, `None` or a `matplotlib.colors.Colormap` object that you want
to convert to a `matplotlib.colors.Colormap` instance. Raises `KeyError`
rather than `ValueError` for missing strings.
- ``matplotlib.cm.register_cmap``; use `matplotlib.colormaps.register
<.ColormapRegistry.register>` instead
- ``matplotlib.cm.unregister_cmap``; use `matplotlib.colormaps.unregister
Expand Down Expand Up @@ -305,7 +311,7 @@ Backend-specific deprecations
private functions if you rely on it.
- ``backend_svg.generate_transform`` and ``backend_svg.generate_css``
- ``backend_tk.NavigationToolbar2Tk.lastrect`` and
``backend_tk.RubberbandTk.lastrect``
``backend_tk.RubberbandTk.lastrect``
- ``backend_tk.NavigationToolbar2Tk.window``; use ``toolbar.master`` instead.
- ``backend_tools.ToolBase.destroy``; To run code upon tool removal, connect to
the ``tool_removed_event`` event.
Expand Down
43 changes: 42 additions & 1 deletion lib/matplotlib/cm.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,39 @@ def unregister(self, name):
"colormap.")
self._cmaps.pop(name, None)

def get_cmap(self, cmap):
"""
Ensure that at given object is a converted to a color map.
If *cmap* in `None`, returns the Colormap named by :rc:`image.cmap`.
Parameters
----------
cmap : str, Colormap, None
- if a `~matplotlib.colors.Colormap`, return it
- if a string, look it up in mpl.colormaps
- if None, look up the default color map in mpl.colormaps
Returns
-------
Colormap
Raises
------
KeyError
"""
# get the default color map
if cmap is None:
return self[mpl.rcParams["image.cmap"]]

# if the user passed in a Colormap, simply return it
if isinstance(cmap, colors.Colormap):
return cmap

# otherwise, it must be a string so look it up
return self[cmap]


# public access to the colormaps should be via `matplotlib.colormaps`. For now,
# we still create the registry here, but that should stay an implementation
Expand Down Expand Up @@ -281,7 +314,12 @@ def _get_cmap(name=None, lut=None):
# pyplot.
get_cmap = _api.deprecated(
'3.6',
name='get_cmap', pending=True, alternative="``matplotlib.colormaps[name]``"
name='get_cmap',
pending=True,
alternative=(
"``matplotlib.colormaps[name]`` " +
"or ``matplotlib.colormaps.get_cmap(obj)``"
)
)(_get_cmap)


Expand Down Expand Up @@ -687,6 +725,8 @@ def _ensure_cmap(cmap):
"""
Ensure that we have a `.Colormap` object.
For internal use to preserve type stability of errors.
Parameters
----------
cmap : None, str, Colormap
Expand All @@ -698,6 +738,7 @@ def _ensure_cmap(cmap):
Returns
-------
Colormap
"""
if isinstance(cmap, colors.Colormap):
return cmap
Expand Down
15 changes: 15 additions & 0 deletions lib/matplotlib/tests/test_colors.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,21 @@ def test_register_cmap():
cm.register_cmap('nome', cmap='not a cmap')


def test_ensure_cmap():
cr = mpl.colormaps
new_cm = mcolors.ListedColormap(cr["viridis"].colors, name='v2')

# check None, str, and Colormap pass
assert cr.get_cmap('plasma') == cr["plasma"]
assert cr.get_cmap(cr["magma"]) == cr["magma"]

# check default default
assert cr.get_cmap(None) == cr[mpl.rcParams['image.cmap']]
bad_cmap = 'AardvarksAreAwkward'
with pytest.raises(KeyError, match=bad_cmap):
cr.get_cmap(bad_cmap)


def test_double_register_builtin_cmap():
name = "viridis"
match = f"Re-registering the builtin cmap {name!r}."
Expand Down

0 comments on commit 283b71d

Please sign in to comment.