Skip to content

Commit 5fc82d1

Browse files
authored
Merge pull request #26965 from UFEddy/deprecate-cm
Removal of deprecated API cm
2 parents 993f22d + 7f23ee1 commit 5fc82d1

File tree

17 files changed

+77
-237
lines changed

17 files changed

+77
-237
lines changed

ci/mypy-stubtest-allowlist.txt

-4
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,6 @@ matplotlib.figure.Figure.set_constrained_layout
3737
matplotlib.figure.Figure.set_constrained_layout_pads
3838
matplotlib.figure.Figure.set_tight_layout
3939

40-
# 3.7 deprecations
41-
matplotlib.cm.register_cmap
42-
matplotlib.cm.unregister_cmap
43-
4440
# positional-only argument name lacking leading underscores
4541
matplotlib.axes._base._AxesBase.axis
4642

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
Removal of top-level cmap registration and access functions in ``mpl.cm``
2+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3+
4+
As part of the `multi-step refactoring of colormap registration
5+
<https://github.com/matplotlib/matplotlib/issues/20853>`_, the following functions have
6+
been removed:
7+
8+
- ``matplotlib.cm.get_cmap``; use ``matplotlib.colormaps[name]`` instead if you
9+
have a `str`.
10+
11+
Use `matplotlib.cm.ColormapRegistry.get_cmap` if you have a `str`, `None` or a
12+
`matplotlib.colors.Colormap` object that you want to convert to a `.Colormap`
13+
object.
14+
- ``matplotlib.cm.register_cmap``; use `matplotlib.colormaps.register
15+
<.ColormapRegistry.register>` instead.
16+
- ``matplotlib.cm.unregister_cmap``; use `matplotlib.colormaps.unregister
17+
<.ColormapRegistry.unregister>` instead.
18+
- ``matplotlib.pyplot.register_cmap``; use `matplotlib.colormaps.register
19+
<.ColormapRegistry.register>` instead.
20+
21+
The `matplotlib.pyplot.get_cmap` function will stay available for backward
22+
compatibility.

doc/api/prev_api_changes/api_changes_0.99.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Changes in 0.99
77
NumPy arrays.
88

99
* User-generated colormaps can now be added to the set recognized
10-
by :func:`matplotlib.cm.get_cmap`. Colormaps can be made the
10+
by ``matplotlib.cm.get_cmap``. Colormaps can be made the
1111
default and applied to the current image using
1212
:func:`matplotlib.pyplot.set_cmap`.
1313

doc/api/prev_api_changes/api_changes_3.2.0/behavior.rst

+5-4
Original file line numberDiff line numberDiff line change
@@ -294,10 +294,11 @@ Exception changes
294294
~~~~~~~~~~~~~~~~~
295295
Various APIs that raised a `ValueError` for incorrectly typed inputs now raise
296296
`TypeError` instead: `.backend_bases.GraphicsContextBase.set_clip_path`,
297-
``blocking_input.BlockingInput.__call__``, `.cm.register_cmap`, `.dviread.DviFont`,
298-
`.rcsetup.validate_hatch`, ``.rcsetup.validate_animation_writer_path``, `.spines.Spine`,
299-
many classes in the :mod:`matplotlib.transforms` module and :mod:`matplotlib.tri`
300-
package, and Axes methods that take a ``norm`` parameter.
297+
``blocking_input.BlockingInput.__call__``, ``matplotlib.cm.register_cmap``,
298+
`.dviread.DviFont`, `.rcsetup.validate_hatch`,
299+
``.rcsetup.validate_animation_writer_path``, `.spines.Spine`, many classes in
300+
the :mod:`matplotlib.transforms` module and :mod:`matplotlib.tri` package, and
301+
Axes methods that take a ``norm`` parameter.
301302

302303
If extra kwargs are passed to `.LogScale`, `TypeError` will now be
303304
raised instead of `ValueError`.

doc/api/prev_api_changes/api_changes_3.3.0/deprecations.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ Please pass capstyles ("miter", "round", "bevel") and joinstyles ("butt",
5555

5656
Passing raw data to ``register_cmap()``
5757
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
58-
Passing raw data via parameters *data* and *lut* to `.register_cmap()` is
58+
Passing raw data via parameters *data* and *lut* to ``matplotlib.cm.register_cmap()`` is
5959
deprecated. Instead, explicitly create a `.LinearSegmentedColormap` and pass
6060
it via the *cmap* parameter:
6161
``register_cmap(cmap=LinearSegmentedColormap(name, data, lut))``.

doc/api/prev_api_changes/api_changes_3.4.0/behaviour.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ time, not at draw time.
203203
Raise or warn on registering a colormap twice
204204
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
205205

206-
When using `matplotlib.cm.register_cmap` to register a user provided or
206+
When using ``matplotlib.cm.register_cmap`` to register a user provided or
207207
third-party colormap it will now raise a `ValueError` if trying to over-write
208208
one of the built in colormaps and warn if trying to over write a user
209209
registered colormap. This may raise for user-registered colormaps in the

doc/api/prev_api_changes/api_changes_3.6.0/behaviour.rst

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ Behaviour changes
44
``plt.get_cmap`` and ``matplotlib.cm.get_cmap`` return a copy
55
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
66

7-
Formerly, `~.pyplot.get_cmap` and `.cm.get_cmap` returned a global version of a
8-
`.Colormap`. This was prone to errors as modification of the colormap would
9-
propagate from one location to another without warning. Now, a new copy of the
10-
colormap is returned.
7+
Formerly, `~.pyplot.get_cmap` and ``matplotlib.cm.get_cmap`` returned a global version
8+
of a `.Colormap`. This was prone to errors as modification of the colormap would
9+
propagate from one location to another without warning. Now, a new copy of the colormap
10+
is returned.
1111

1212
Large ``imshow`` images are now downsampled
1313
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

doc/api/prev_api_changes/api_changes_3.7.0/behaviour.rst

+4-4
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ also be based on ``mpl_toolkits.axisartist``. This behavior is consistent with
2020
``plt.get_cmap`` and ``matplotlib.cm.get_cmap`` return a copy
2121
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2222

23-
Formerly, `~.pyplot.get_cmap` and `.cm.get_cmap` returned a global version of a
24-
`.Colormap`. This was prone to errors as modification of the colormap would
25-
propagate from one location to another without warning. Now, a new copy of the
26-
colormap is returned.
23+
Formerly, `~.pyplot.get_cmap` and ``matplotlib.cm.get_cmap`` returned a global version
24+
of a `.Colormap`. This was prone to errors as modification of the colormap would
25+
propagate from one location to another without warning. Now, a new copy of the colormap
26+
is returned.
2727

2828
``TrapezoidMapTriFinder`` uses different random number generator
2929
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

doc/users/prev_whats_new/whats_new_1.2.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ minimum and maximum colorbar extensions.
8686
Z = np.cos(X) * np.sin(0.5*Y)
8787

8888
clevs = [-.75, -.5, -.25, 0., .25, .5, .75]
89-
cmap = plt.cm.get_cmap(name='jet', lut=8)
89+
cmap = plt.get_cmap(name='jet', lut=8)
9090

9191
ax1 = plt.subplot(211)
9292
cs1 = plt.contourf(x, y, Z, clevs, cmap=cmap, extend='both')

doc/users/prev_whats_new/whats_new_3.4.0.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,7 @@ for out-of-range and masked values.
547547
New ``cm.unregister_cmap`` function
548548
-----------------------------------
549549

550-
`.cm.unregister_cmap` allows users to remove a colormap that they have
550+
``matplotlib.cm.unregister_cmap`` allows users to remove a colormap that they have
551551
previously registered.
552552

553553
New ``CenteredNorm`` for symmetrical data around a center

doc/users/prev_whats_new/whats_new_3.5.0.rst

+3-3
Original file line numberDiff line numberDiff line change
@@ -148,9 +148,9 @@ To register new colormaps use::
148148

149149
plt.colormaps.register(my_colormap)
150150

151-
We recommend to use the new API instead of the `~.cm.get_cmap` and
152-
`~.cm.register_cmap` functions for new code. `matplotlib.cm.get_cmap` and
153-
`matplotlib.cm.register_cmap` will eventually be deprecated and removed.
151+
We recommend to use the new API instead of the ``matplotlib.cm.get_cmap`` and
152+
``matplotlib.cm.register_cmap`` functions for new code. ``matplotlib.cm.get_cmap`` and
153+
``matplotlib.cm.register_cmap`` will eventually be deprecated and removed.
154154
Within `.pyplot`, ``plt.get_cmap()`` and ``plt.register_cmap()`` will continue
155155
to be supported for backward compatibility.
156156

galleries/examples/color/custom_cmap.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -279,4 +279,4 @@
279279
# - `matplotlib.colors.LinearSegmentedColormap.from_list`
280280
# - `matplotlib.cm`
281281
# - `matplotlib.cm.ScalarMappable.set_cmap`
282-
# - `matplotlib.cm.register_cmap`
282+
# - `matplotlib.cm.ColormapRegistry.register`

lib/matplotlib/_cm.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ def _ch_helper(gamma, s, r, h, p0, p1, x):
6666
def cubehelix(gamma=1.0, s=0.5, r=-1.5, h=1.0):
6767
"""
6868
Return custom data dictionary of (r, g, b) conversion functions, which can
69-
be used with :func:`register_cmap`, for the cubehelix color scheme.
69+
be used with `.ColormapRegistry.register`, for the cubehelix color scheme.
7070
7171
Unlike most other color schemes cubehelix was designed by D.A. Green to
7272
be monotonically increasing in terms of perceived brightness.

lib/matplotlib/cm.py

+2-129
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,6 @@ class ColormapRegistry(Mapping):
8383
def __init__(self, cmaps):
8484
self._cmaps = cmaps
8585
self._builtin_cmaps = tuple(cmaps)
86-
# A shim to allow register_cmap() to force an override
87-
self._allow_override_builtin = False
8886

8987
def __getitem__(self, item):
9088
try:
@@ -146,10 +144,8 @@ def register(self, cmap, *, name=None, force=False):
146144
# unless explicitly asked to
147145
raise ValueError(
148146
f'A colormap named "{name}" is already registered.')
149-
elif (name in self._builtin_cmaps
150-
and not self._allow_override_builtin):
151-
# We don't allow overriding a builtin unless privately
152-
# coming from register_cmap()
147+
elif name in self._builtin_cmaps:
148+
# We don't allow overriding a builtin.
153149
raise ValueError("Re-registering the builtin cmap "
154150
f"{name!r} is not allowed.")
155151

@@ -236,129 +232,6 @@ def get_cmap(self, cmap):
236232
globals().update(_colormaps)
237233

238234

239-
@_api.deprecated("3.7", alternative="``matplotlib.colormaps.register(name)``")
240-
def register_cmap(name=None, cmap=None, *, override_builtin=False):
241-
"""
242-
Add a colormap to the set recognized by :func:`get_cmap`.
243-
244-
Register a new colormap to be accessed by name ::
245-
246-
LinearSegmentedColormap('swirly', data, lut)
247-
register_cmap(cmap=swirly_cmap)
248-
249-
Parameters
250-
----------
251-
name : str, optional
252-
The name that can be used in :func:`get_cmap` or :rc:`image.cmap`
253-
254-
If absent, the name will be the :attr:`~matplotlib.colors.Colormap.name`
255-
attribute of the *cmap*.
256-
257-
cmap : matplotlib.colors.Colormap
258-
Despite being the second argument and having a default value, this
259-
is a required argument.
260-
261-
override_builtin : bool
262-
263-
Allow built-in colormaps to be overridden by a user-supplied
264-
colormap.
265-
266-
Please do not use this unless you are sure you need it.
267-
"""
268-
_api.check_isinstance((str, None), name=name)
269-
if name is None:
270-
try:
271-
name = cmap.name
272-
except AttributeError as err:
273-
raise ValueError("Arguments must include a name or a "
274-
"Colormap") from err
275-
# override_builtin is allowed here for backward compatibility
276-
# this is just a shim to enable that to work privately in
277-
# the global ColormapRegistry
278-
_colormaps._allow_override_builtin = override_builtin
279-
_colormaps.register(cmap, name=name, force=override_builtin)
280-
_colormaps._allow_override_builtin = False
281-
282-
283-
def _get_cmap(name=None, lut=None):
284-
"""
285-
Get a colormap instance, defaulting to rc values if *name* is None.
286-
287-
Parameters
288-
----------
289-
name : `~matplotlib.colors.Colormap` or str or None, default: None
290-
If a `.Colormap` instance, it will be returned. Otherwise, the name of
291-
a colormap known to Matplotlib, which will be resampled by *lut*. The
292-
default, None, means :rc:`image.cmap`.
293-
lut : int or None, default: None
294-
If *name* is not already a Colormap instance and *lut* is not None, the
295-
colormap will be resampled to have *lut* entries in the lookup table.
296-
297-
Returns
298-
-------
299-
Colormap
300-
"""
301-
if name is None:
302-
name = mpl.rcParams['image.cmap']
303-
if isinstance(name, colors.Colormap):
304-
return name
305-
_api.check_in_list(sorted(_colormaps), name=name)
306-
if lut is None:
307-
return _colormaps[name]
308-
else:
309-
return _colormaps[name].resampled(lut)
310-
311-
# do it in two steps like this so we can have an un-deprecated version in
312-
# pyplot.
313-
get_cmap = _api.deprecated(
314-
'3.7',
315-
name='get_cmap',
316-
alternative=(
317-
"``matplotlib.colormaps[name]`` " +
318-
"or ``matplotlib.colormaps.get_cmap(obj)``"
319-
)
320-
)(_get_cmap)
321-
322-
323-
@_api.deprecated("3.7",
324-
alternative="``matplotlib.colormaps.unregister(name)``")
325-
def unregister_cmap(name):
326-
"""
327-
Remove a colormap recognized by :func:`get_cmap`.
328-
329-
You may not remove built-in colormaps.
330-
331-
If the named colormap is not registered, returns with no error, raises
332-
if you try to de-register a default colormap.
333-
334-
.. warning::
335-
336-
Colormap names are currently a shared namespace that may be used
337-
by multiple packages. Use `unregister_cmap` only if you know you
338-
have registered that name before. In particular, do not
339-
unregister just in case to clean the name before registering a
340-
new colormap.
341-
342-
Parameters
343-
----------
344-
name : str
345-
The name of the colormap to be un-registered
346-
347-
Returns
348-
-------
349-
ColorMap or None
350-
If the colormap was registered, return it if not return `None`
351-
352-
Raises
353-
------
354-
ValueError
355-
If you try to de-register a default built-in colormap.
356-
"""
357-
cmap = _colormaps.get(name, None)
358-
_colormaps.unregister(name)
359-
return cmap
360-
361-
362235
def _auto_norm_from_scale(scale_cls):
363236
"""
364237
Automatically generate a norm class from *scale_cls*.

lib/matplotlib/cm.pyi

-2
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ class ColormapRegistry(Mapping[str, colors.Colormap]):
1919

2020
_colormaps: ColormapRegistry = ...
2121

22-
def get_cmap(name: str | colors.Colormap | None = ..., lut: int | None = ...) -> colors.Colormap: ...
23-
2422
class ScalarMappable:
2523
cmap: colors.Colormap | None
2624
colorbar: Colorbar | None

lib/matplotlib/pyplot.py

+29-13
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,7 @@
7474
from matplotlib.scale import get_scale_names # noqa: F401
7575

7676
from matplotlib.cm import _colormaps
77-
from matplotlib.cm import register_cmap # type: ignore # noqa: F401
78-
from matplotlib.colors import _color_sequences
77+
from matplotlib.colors import _color_sequences, Colormap
7978

8079
import numpy as np
8180

@@ -104,7 +103,6 @@
104103
QuadMesh,
105104
)
106105
from matplotlib.colorbar import Colorbar
107-
from matplotlib.colors import Colormap
108106
from matplotlib.container import (
109107
BarContainer,
110108
ErrorbarContainer,
@@ -2362,14 +2360,33 @@ def clim(vmin: float | None = None, vmax: float | None = None) -> None:
23622360
im.set_clim(vmin, vmax)
23632361

23642362

2365-
# eventually this implementation should move here, use indirection for now to
2366-
# avoid having two copies of the code floating around.
2367-
def get_cmap(
2368-
name: Colormap | str | None = None,
2369-
lut: int | None = None
2370-
) -> Colormap:
2371-
return cm._get_cmap(name=name, lut=lut) # type: ignore
2372-
get_cmap.__doc__ = cm._get_cmap.__doc__ # type: ignore
2363+
def get_cmap(name: Colormap | str | None = None, lut: int | None = None) -> Colormap:
2364+
"""
2365+
Get a colormap instance, defaulting to rc values if *name* is None.
2366+
2367+
Parameters
2368+
----------
2369+
name : `~matplotlib.colors.Colormap` or str or None, default: None
2370+
If a `.Colormap` instance, it will be returned. Otherwise, the name of
2371+
a colormap known to Matplotlib, which will be resampled by *lut*. The
2372+
default, None, means :rc:`image.cmap`.
2373+
lut : int or None, default: None
2374+
If *name* is not already a Colormap instance and *lut* is not None, the
2375+
colormap will be resampled to have *lut* entries in the lookup table.
2376+
2377+
Returns
2378+
-------
2379+
Colormap
2380+
"""
2381+
if name is None:
2382+
name = rcParams['image.cmap']
2383+
if isinstance(name, Colormap):
2384+
return name
2385+
_api.check_in_list(sorted(_colormaps), name=name)
2386+
if lut is None:
2387+
return _colormaps[name]
2388+
else:
2389+
return _colormaps[name].resampled(lut)
23732390

23742391

23752392
def set_cmap(cmap: Colormap | str) -> None:
@@ -2384,8 +2401,7 @@ def set_cmap(cmap: Colormap | str) -> None:
23842401
See Also
23852402
--------
23862403
colormaps
2387-
matplotlib.cm.register_cmap
2388-
matplotlib.cm.get_cmap
2404+
get_cmap
23892405
"""
23902406
cmap = get_cmap(cmap)
23912407

0 commit comments

Comments
 (0)