Skip to content

Backport PR #20935 on branch v3.5.x (Add ColormapsRegistry as experimental and add it to pyplot) #21099

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion doc/api/pyplot_summary.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,5 @@ For a more in-depth look at colormaps, see the

.. currentmodule:: matplotlib.pyplot

.. autofunction:: colormaps
.. autodata:: colormaps
:no-value:
24 changes: 14 additions & 10 deletions doc/users/next_whats_new/colormaps.rst
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
Colormap registry
------------------
Colormap registry (experimental)
--------------------------------

Colormaps are now managed via `matplotlib.colormaps`, which is a
`.ColormapRegistry`.
Colormaps are now managed via `matplotlib.colormaps` (or `.pyplot.colormaps`),
which is a `.ColormapRegistry`. While we are confident that the API is final,
we formally mark it as experimental for 3.5 because we want to keep the option
to still adapt the API for 3.6 should the need arise.

Colormaps can be obtained using item access::

import matplotlib as mpl
cmap = mpl.colormaps['viridis']
import matplotlib.pyplot as plt
cmap = plt.colormaps['viridis']

To register new colormaps use::

mpl.colormaps.register(my_colormap)
plt.colormaps.register(my_colormap)

The use of `matplotlib.cm.get_cmap` and `matplotlib.cm.register_cmap` is
discouraged in favor of the above. Within `.pyplot` the use of
``plt.get_cmap()`` and ``plt.register_cmap()`` will continue to be supported.
We recommend to use the new API instead of the `~.cm.get_cmap` and
`~.cm.register_cmap` functions for new code. `matplotlib.cm.get_cmap` and
`matplotlib.cm.register_cmap` will eventually be deprecated and removed.
Within `.pyplot` ``plt.get_cmap()`` and ``plt.register_cmap()`` will continue
to be supported for backward compatibility.
3 changes: 1 addition & 2 deletions examples/images_contours_and_fields/contourf_demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
How to use the `.axes.Axes.contourf` method to create filled contour plots.
"""
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt

origin = 'lower'
Expand Down Expand Up @@ -87,7 +86,7 @@

# Illustrate all 4 possible "extend" settings:
extends = ["neither", "both", "min", "max"]
cmap = mpl.colormaps["winter"].with_extremes(under="magenta", over="yellow")
cmap = plt.colormaps["winter"].with_extremes(under="magenta", over="yellow")
# Note: contouring simply excludes masked or nan regions, so
# instead of using the "bad" colormap value for them, it draws
# nothing at all in them. Therefore the following would have
Expand Down
3 changes: 1 addition & 2 deletions examples/images_contours_and_fields/demo_bboximage.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
a bounding box. This demo shows how to show an image inside a `.text.Text`'s
bounding box as well as how to manually create a bounding box for the image.
"""
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.image import BboxImage
Expand Down Expand Up @@ -39,7 +38,7 @@
a = np.vstack((a, a))

# List of all colormaps; skip reversed colormaps.
cmap_names = sorted(m for m in mpl.colormaps if not m.endswith("_r"))
cmap_names = sorted(m for m in plt.colormaps if not m.endswith("_r"))

ncol = 2
nrow = len(cmap_names) // ncol + 1
Expand Down
2 changes: 1 addition & 1 deletion examples/images_contours_and_fields/pcolormesh_levels.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@

# pick the desired colormap, sensible levels, and define a normalization
# instance which takes data values and translates those into levels.
cmap = plt.get_cmap('PiYG')
cmap = plt.colormaps['PiYG']
norm = BoundaryNorm(levels, ncolors=cmap.N, clip=True)

fig, (ax0, ax1) = plt.subplots(nrows=2)
Expand Down
3 changes: 1 addition & 2 deletions examples/images_contours_and_fields/quadmesh_demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
This demo illustrates a bug in quadmesh with masked data.
"""

import matplotlib as mpl
from matplotlib import pyplot as plt
import numpy as np

Expand All @@ -30,7 +29,7 @@
axs[0].set_title('Without masked values')

# You can control the color of the masked region.
cmap = mpl.colormaps[mpl.rcParams['image.cmap']].with_extremes(bad='y')
cmap = plt.colormaps[plt.rcParams['image.cmap']].with_extremes(bad='y')
axs[1].pcolormesh(Qx, Qz, Zm, shading='gouraud', cmap=cmap)
axs[1].set_title('With masked values')

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def survey(results, category_names):
labels = list(results.keys())
data = np.array(list(results.values()))
data_cum = data.cumsum(axis=1)
category_colors = plt.get_cmap('RdYlGn')(
category_colors = plt.colormaps['RdYlGn'](
np.linspace(0.15, 0.85, data.shape[1]))

fig, ax = plt.subplots(figsize=(9.2, 5))
Expand Down
2 changes: 1 addition & 1 deletion examples/mplot3d/polys3d.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def polygon_under_graph(x, y):

# verts[i] is a list of (x, y) pairs defining polygon i.
verts = [polygon_under_graph(x, poisson.pmf(l, x)) for l in lambdas]
facecolors = plt.get_cmap('viridis_r')(np.linspace(0, 1, len(verts)))
facecolors = plt.colormaps['viridis_r'](np.linspace(0, 1, len(verts)))

poly = PolyCollection(verts, facecolors=facecolors, alpha=.7)
ax.add_collection3d(poly, zs=lambdas, zdir='y')
Expand Down
5 changes: 2 additions & 3 deletions examples/pie_and_polar_charts/nested_pie.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

"""

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np

Expand All @@ -31,7 +30,7 @@
size = 0.3
vals = np.array([[60., 32.], [37., 40.], [29., 10.]])

cmap = mpl.colormaps["tab20c"]
cmap = plt.colormaps["tab20c"]
outer_colors = cmap(np.arange(3)*4)
inner_colors = cmap([1, 2, 5, 6, 9, 10])

Expand Down Expand Up @@ -62,7 +61,7 @@
# Obtain the ordinates of the bar edges
valsleft = np.cumsum(np.append(0, valsnorm.flatten()[:-1])).reshape(vals.shape)

cmap = mpl.colormaps["tab20c"]
cmap = plt.colormaps["tab20c"]
outer_colors = cmap(np.arange(3)*4)
inner_colors = cmap([1, 2, 5, 6, 9, 10])

Expand Down
2 changes: 1 addition & 1 deletion examples/userdemo/colormap_interactive_adjustment.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def adjust_colorbar(mouseevent):
Z2 = np.exp(-(X - 1)**2 - (Y - 1)**2)
Z = (0.9*Z1 - 0.5*Z2) * 2

cmap = plt.get_cmap('viridis').with_extremes(
cmap = plt.colormaps['viridis'].with_extremes(
over='xkcd:orange', under='xkcd:dark red')
axesimage = plt.imshow(Z, cmap=cmap)
colorbar = plt.colorbar(axesimage, ax=ax, use_gridspec=True)
Expand Down
16 changes: 16 additions & 0 deletions lib/matplotlib/cm.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,12 @@ class ColormapRegistry(Mapping):
r"""
Container for colormaps that are known to Matplotlib by name.

.. admonition:: Experimental

While we expect the API to be final, we formally mark it as
experimental for 3.5 because we want to keep the option to still adapt
the API for 3.6 should the need arise.

The universal registry instance is `matplotlib.colormaps`. There should be
no need for users to instantiate `.ColormapRegistry` themselves.

Expand Down Expand Up @@ -136,6 +142,16 @@ def __str__(self):
return ('ColormapRegistry; available colormaps:\n' +
', '.join(f"'{name}'" for name in self))

def __call__(self):
"""
Return a list of the registered colormap names.

This exists only for backward-compatibilty in `.pyplot` which had a
``plt.colormaps()`` method. The recommended way to get this list is
now ``list(colormaps)``.
"""
return list(self)

def register(self, cmap, *, name=None, force=False):
"""
Register a new colormap.
Expand Down
Loading