Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 9b1fcf6

Browse filesBrowse files
authored
Merge pull request #23668 from tacaswell/api_deprecate_cmap_functions
Api deprecate cmap functions
2 parents e17b602 + 014c1ea commit 9b1fcf6
Copy full SHA for 9b1fcf6

File tree

Expand file treeCollapse file tree

21 files changed

+217
-96
lines changed
Filter options
Expand file treeCollapse file tree

21 files changed

+217
-96
lines changed
+22Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
Pending deprecation top-level cmap registration and access functions in ``mpl.cm``
2+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3+
4+
As part of a `multi-step process
5+
<https://github.com/matplotlib/matplotlib/issues/20853>`_ we are refactoring
6+
the global state for managing the registered colormaps.
7+
8+
In Matplotlib 3.5 we added a `.ColormapRegistry` class and exposed an
9+
instance at the top level as ``matplotlib.colormaps``. The existing
10+
top level functions in `matplotlib.cm` (``get_cmap``, ``register_cmap``,
11+
``unregister_cmap``) were changed to be aliases around the same instance.
12+
13+
In Matplotlib 3.6 we have marked those top level functions as pending
14+
deprecation with the intention of deprecation in Matplotlib 3.7. The
15+
following functions have been marked for pending deprecation:
16+
17+
- `matplotlib.cm.get_cmap` - use ``matplotlib.colormaps[name]`` instead
18+
- `matplotlib.cm.register_cmap` - use ``matplotlib.colormaps.register`` instead
19+
- `matplotlib.cm.unregister_cmap` - use ``matplotlib.colormaps.unregister`` instead
20+
- ``matplotlib.pyplot.register_cmap`` - use ``matplotlib.colormaps.register`` instead
21+
22+
The `matplotlib.pyplot.get_cmap` function will stay available for backward compatibility.

‎doc/api/pyplot_summary.rst

Copy file name to clipboardExpand all lines: doc/api/pyplot_summary.rst
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ Plotting commands
6464
gcf
6565
gci
6666
get
67+
get_cmap
6768
get_figlabels
6869
get_fignums
6970
getp
+13Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
Colormap method for creating a different lookup table size
2+
----------------------------------------------------------
3+
The new method `.Colormap.resampled` creates a new `.Colormap` instance
4+
with the specified lookup table size. This is a replacement for manipulating
5+
the lookup table size via ``get_cmap``.
6+
7+
Use::
8+
9+
get_cmap(name).resampled(N)
10+
11+
instead of::
12+
13+
get_cmap(name, lut=N)

‎examples/images_contours_and_fields/contour_image.py

Copy file name to clipboardExpand all lines: examples/images_contours_and_fields/contour_image.py
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
axs = _axs.flatten()
4242

4343
cset1 = axs[0].contourf(X, Y, Z, levels, norm=norm,
44-
cmap=cm.get_cmap(cmap, len(levels) - 1))
44+
cmap=cmap.resampled(len(levels) - 1))
4545
# It is not necessary, but for the colormap, we need only the
4646
# number of levels minus 1. To avoid discretization error, use
4747
# either this number or a large number such as the default (256).

‎examples/images_contours_and_fields/image_annotated_heatmap.py

Copy file name to clipboardExpand all lines: examples/images_contours_and_fields/image_annotated_heatmap.py
+2-1Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939

4040
import numpy as np
4141
import matplotlib
42+
import matplotlib as mpl
4243
import matplotlib.pyplot as plt
4344
# sphinx_gallery_thumbnail_number = 2
4445

@@ -272,7 +273,7 @@ def annotate_heatmap(im, data=None, valfmt="{x:.2f}",
272273
fmt = matplotlib.ticker.FuncFormatter(lambda x, pos: qrates[::-1][norm(x)])
273274

274275
im, _ = heatmap(data, y, x, ax=ax3,
275-
cmap=plt.get_cmap("PiYG", 7), norm=norm,
276+
cmap=mpl.colormaps["PiYG"].resampled(7), norm=norm,
276277
cbar_kw=dict(ticks=np.arange(-3, 4), format=fmt),
277278
cbarlabel="Quality Rating")
278279

‎examples/lines_bars_and_markers/multivariate_marker_plot.py

Copy file name to clipboardExpand all lines: examples/lines_bars_and_markers/multivariate_marker_plot.py
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
positions = np.random.normal(size=(N, 2)) * 5
3232
data = zip(skills, takeoff_angles, thrusts, successful, positions)
3333

34-
cmap = plt.cm.get_cmap("plasma")
34+
cmap = plt.colormaps["plasma"]
3535
fig, ax = plt.subplots()
3636
fig.suptitle("Throwing success", size=14)
3737
for skill, takeoff, thrust, mood, pos in data:

‎lib/matplotlib/cm.py

Copy file name to clipboardExpand all lines: lib/matplotlib/cm.py
+47-7Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,11 @@ def unregister(self, name):
201201
globals().update(_colormaps)
202202

203203

204+
@_api.deprecated(
205+
'3.6',
206+
pending=True,
207+
alternative="``matplotlib.colormaps.register_cmap(name)``"
208+
)
204209
def register_cmap(name=None, cmap=None, *, override_builtin=False):
205210
"""
206211
Add a colormap to the set recognized by :func:`get_cmap`.
@@ -244,13 +249,10 @@ def register_cmap(name=None, cmap=None, *, override_builtin=False):
244249
_colormaps._allow_override_builtin = False
245250

246251

247-
def get_cmap(name=None, lut=None):
252+
def _get_cmap(name=None, lut=None):
248253
"""
249254
Get a colormap instance, defaulting to rc values if *name* is None.
250255
251-
Colormaps added with :func:`register_cmap` take precedence over
252-
built-in colormaps.
253-
254256
Parameters
255257
----------
256258
name : `matplotlib.colors.Colormap` or str or None, default: None
@@ -260,6 +262,10 @@ def get_cmap(name=None, lut=None):
260262
lut : int or None, default: None
261263
If *name* is not already a Colormap instance and *lut* is not None, the
262264
colormap will be resampled to have *lut* entries in the lookup table.
265+
266+
Returns
267+
-------
268+
Colormap
263269
"""
264270
if name is None:
265271
name = mpl.rcParams['image.cmap']
@@ -269,9 +275,20 @@ def get_cmap(name=None, lut=None):
269275
if lut is None:
270276
return _colormaps[name]
271277
else:
272-
return _colormaps[name]._resample(lut)
278+
return _colormaps[name].resampled(lut)
273279

280+
# do it in two steps like this so we can have an un-deprecated version in
281+
# pyplot.
282+
get_cmap = _api.deprecated(
283+
'3.6', pending=True, alternative="``matplotlib.colormaps[name]``"
284+
)(_get_cmap)
274285

286+
287+
@_api.deprecated(
288+
'3.6',
289+
pending=True,
290+
alternative="``matplotlib.colormaps.unregister_cmap(name)``"
291+
)
275292
def unregister_cmap(name):
276293
"""
277294
Remove a colormap recognized by :func:`get_cmap`.
@@ -550,8 +567,8 @@ def set_cmap(self, cmap):
550567
cmap : `.Colormap` or str or None
551568
"""
552569
in_init = self.cmap is None
553-
cmap = get_cmap(cmap)
554-
self.cmap = cmap
570+
571+
self.cmap = _ensure_cmap(cmap)
555572
if not in_init:
556573
self.changed() # Things are not set up properly yet.
557574

@@ -663,3 +680,26 @@ def changed(self):
663680
*vmin*/*vmax* when a *norm* instance is given (but using a `str` *norm*
664681
name together with *vmin*/*vmax* is acceptable).""",
665682
)
683+
684+
685+
def _ensure_cmap(cmap):
686+
"""
687+
Ensure that we have a `.Colormap` object.
688+
689+
Parameters
690+
----------
691+
cmap : None, str, Colormap
692+
693+
- if a `Colormap`, return it
694+
- if a string, look it up in mpl.colormaps
695+
- if None, look up the default color map in mpl.colormaps
696+
697+
Returns
698+
-------
699+
Colormap
700+
"""
701+
if isinstance(cmap, colors.Colormap):
702+
return cmap
703+
return mpl.colormaps[
704+
cmap if cmap is not None else mpl.rcParams['image.cmap']
705+
]

‎lib/matplotlib/colors.py

Copy file name to clipboardExpand all lines: lib/matplotlib/colors.py
+12-3Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -853,8 +853,17 @@ def is_gray(self):
853853
return (np.all(self._lut[:, 0] == self._lut[:, 1]) and
854854
np.all(self._lut[:, 0] == self._lut[:, 2]))
855855

856-
def _resample(self, lutsize):
856+
def resampled(self, lutsize):
857857
"""Return a new colormap with *lutsize* entries."""
858+
if hasattr(self, '_resample'):
859+
_api.warn_external(
860+
"The ability to resample a color map is now public API "
861+
f"However the class {type(self)} still only implements "
862+
"the previous private _resample method. Please update "
863+
"your class."
864+
)
865+
return self._resample(lutsize)
866+
858867
raise NotImplementedError()
859868

860869
def reversed(self, name=None):
@@ -1049,7 +1058,7 @@ def from_list(name, colors, N=256, gamma=1.0):
10491058

10501059
return LinearSegmentedColormap(name, cdict, N, gamma)
10511060

1052-
def _resample(self, lutsize):
1061+
def resampled(self, lutsize):
10531062
"""Return a new colormap with *lutsize* entries."""
10541063
new_cmap = LinearSegmentedColormap(self.name, self._segmentdata,
10551064
lutsize)
@@ -1153,7 +1162,7 @@ def _init(self):
11531162
self._isinit = True
11541163
self._set_extremes()
11551164

1156-
def _resample(self, lutsize):
1165+
def resampled(self, lutsize):
11571166
"""Return a new colormap with *lutsize* entries."""
11581167
colors = self(np.linspace(0, 1, lutsize))
11591168
new_cmap = ListedColormap(colors, name=self.name)

‎lib/matplotlib/pyplot.py

Copy file name to clipboardExpand all lines: lib/matplotlib/pyplot.py
+9-2Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@
6868
from matplotlib.scale import get_scale_names
6969

7070
from matplotlib import cm
71-
from matplotlib.cm import _colormaps as colormaps, get_cmap, register_cmap
71+
from matplotlib.cm import _colormaps as colormaps, register_cmap
7272
from matplotlib.colors import _color_sequences as color_sequences
7373

7474
import numpy as np
@@ -2075,6 +2075,13 @@ def clim(vmin=None, vmax=None):
20752075
im.set_clim(vmin, vmax)
20762076

20772077

2078+
# eventually this implementation should move here, use indirection for now to
2079+
# avoid having two copies of the code floating around.
2080+
def get_cmap(name=None, lut=None):
2081+
return cm._get_cmap(name=name, lut=lut)
2082+
get_cmap.__doc__ = cm._get_cmap.__doc__
2083+
2084+
20782085
def set_cmap(cmap):
20792086
"""
20802087
Set the default colormap, and applies it to the current image if any.
@@ -2090,7 +2097,7 @@ def set_cmap(cmap):
20902097
matplotlib.cm.register_cmap
20912098
matplotlib.cm.get_cmap
20922099
"""
2093-
cmap = cm.get_cmap(cmap)
2100+
cmap = get_cmap(cmap)
20942101

20952102
rc('image', cmap=cmap.name)
20962103
im = gci()

‎lib/matplotlib/streamplot.py

Copy file name to clipboardExpand all lines: lib/matplotlib/streamplot.py
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ def streamplot(axes, x, y, u, v, density=1, linewidth=None, color=None,
187187
if use_multicolor_lines:
188188
if norm is None:
189189
norm = mcolors.Normalize(color.min(), color.max())
190-
cmap = cm.get_cmap(cmap)
190+
cmap = cm._ensure_cmap(cmap)
191191

192192
streamlines = []
193193
arrows = []

‎lib/matplotlib/tests/test_artist.py

Copy file name to clipboardExpand all lines: lib/matplotlib/tests/test_artist.py
+3-3Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
import pytest
77

8-
from matplotlib import cm
98
import matplotlib.colors as mcolors
109
import matplotlib.pyplot as plt
1110
import matplotlib.patches as mpatches
@@ -14,6 +13,7 @@
1413
import matplotlib.transforms as mtransforms
1514
import matplotlib.collections as mcollections
1615
import matplotlib.artist as martist
16+
import matplotlib as mpl
1717
from matplotlib.testing.decorators import check_figures_equal, image_comparison
1818

1919

@@ -415,7 +415,7 @@ def test_format_cursor_data_BoundaryNorm():
415415
# map range -1..1 to 0..256 in 0.01 steps
416416
fig, ax = plt.subplots()
417417
fig.suptitle("-1..1 to 0..256 in 0.01")
418-
cmap = cm.get_cmap('RdBu_r', 200)
418+
cmap = mpl.colormaps['RdBu_r'].resampled(200)
419419
norm = mcolors.BoundaryNorm(np.linspace(-1, 1, 200), 200)
420420
img = ax.imshow(X, cmap=cmap, norm=norm)
421421

@@ -439,7 +439,7 @@ def test_format_cursor_data_BoundaryNorm():
439439
# map range -1..1 to 0..256 in 0.01 steps
440440
fig, ax = plt.subplots()
441441
fig.suptitle("-1..1 to 0..256 in 0.001")
442-
cmap = cm.get_cmap('RdBu_r', 2000)
442+
cmap = mpl.colormaps['RdBu_r'].resampled(2000)
443443
norm = mcolors.BoundaryNorm(np.linspace(-1, 1, 2000), 2000)
444444
img = ax.imshow(X, cmap=cmap, norm=norm)
445445

‎lib/matplotlib/tests/test_axes.py

Copy file name to clipboardExpand all lines: lib/matplotlib/tests/test_axes.py
+6-6Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1220,7 +1220,7 @@ def test_pcolormesh_alpha():
12201220
Qy = Y + np.sin(X)
12211221
Z = np.hypot(X, Y) / 5
12221222
Z = (Z - Z.min()) / Z.ptp()
1223-
vir = plt.get_cmap("viridis", 16)
1223+
vir = mpl.colormaps["viridis"].resampled(16)
12241224
# make another colormap with varying alpha
12251225
colors = vir(np.arange(16))
12261226
colors[:, 3] = 0.5 + 0.5*np.sin(np.arange(16))
@@ -2279,7 +2279,7 @@ def test_contour_hatching():
22792279
x, y, z = contour_dat()
22802280
fig, ax = plt.subplots()
22812281
ax.contourf(x, y, z, 7, hatches=['/', '\\', '//', '-'],
2282-
cmap=plt.get_cmap('gray'),
2282+
cmap=mpl.colormaps['gray'],
22832283
extend='both', alpha=0.5)
22842284

22852285

@@ -2289,7 +2289,7 @@ def test_contour_colorbar():
22892289

22902290
fig, ax = plt.subplots()
22912291
cs = ax.contourf(x, y, z, levels=np.arange(-1.8, 1.801, 0.2),
2292-
cmap=plt.get_cmap('RdBu'),
2292+
cmap=mpl.colormaps['RdBu'],
22932293
vmin=-0.6,
22942294
vmax=0.6,
22952295
extend='both')
@@ -2473,7 +2473,7 @@ def test_scatter_edgecolor_RGB(self):
24732473
@check_figures_equal(extensions=["png"])
24742474
def test_scatter_invalid_color(self, fig_test, fig_ref):
24752475
ax = fig_test.subplots()
2476-
cmap = plt.get_cmap("viridis", 16)
2476+
cmap = mpl.colormaps["viridis"].resampled(16)
24772477
cmap.set_bad("k", 1)
24782478
# Set a nonuniform size to prevent the last call to `scatter` (plotting
24792479
# the invalid points separately in fig_ref) from using the marker
@@ -2482,15 +2482,15 @@ def test_scatter_invalid_color(self, fig_test, fig_ref):
24822482
c=[1, np.nan, 2, np.nan], s=[1, 2, 3, 4],
24832483
cmap=cmap, plotnonfinite=True)
24842484
ax = fig_ref.subplots()
2485-
cmap = plt.get_cmap("viridis", 16)
2485+
cmap = mpl.colormaps["viridis"].resampled(16)
24862486
ax.scatter([0, 2], [0, 2], c=[1, 2], s=[1, 3], cmap=cmap)
24872487
ax.scatter([1, 3], [1, 3], s=[2, 4], color="k")
24882488

24892489
@check_figures_equal(extensions=["png"])
24902490
def test_scatter_no_invalid_color(self, fig_test, fig_ref):
24912491
# With plotnonfinite=False we plot only 2 points.
24922492
ax = fig_test.subplots()
2493-
cmap = plt.get_cmap("viridis", 16)
2493+
cmap = mpl.colormaps["viridis"].resampled(16)
24942494
cmap.set_bad("k", 1)
24952495
ax.scatter(range(4), range(4),
24962496
c=[1, np.nan, 2, np.nan], s=[1, 2, 3, 4],

‎lib/matplotlib/tests/test_collections.py

Copy file name to clipboardExpand all lines: lib/matplotlib/tests/test_collections.py
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -955,7 +955,7 @@ def test_quadmesh_set_array():
955955
def test_quadmesh_vmin_vmax():
956956
# test when vmin/vmax on the norm changes, the quadmesh gets updated
957957
fig, ax = plt.subplots()
958-
cmap = mpl.cm.get_cmap('plasma')
958+
cmap = mpl.colormaps['plasma']
959959
norm = mpl.colors.Normalize(vmin=0, vmax=1)
960960
coll = ax.pcolormesh([[1]], cmap=cmap, norm=norm)
961961
fig.canvas.draw()

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.