Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 40f4013

Browse files
committed
Add a dedicated ColormapRegistry class
1 parent 2967365 commit 40f4013

File tree

5 files changed

+105
-3
lines changed

5 files changed

+105
-3
lines changed

.flake8

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ per-file-ignores =
4545
setupext.py: E501
4646
tests.py: F401
4747

48-
lib/matplotlib/__init__.py: F401
48+
lib/matplotlib/__init__.py: E402, F401
4949
lib/matplotlib/_api/__init__.py: F401
5050
lib/matplotlib/_cm.py: E122, E202, E203, E302
5151
lib/matplotlib/_mathtext.py: E221, E251

doc/api/matplotlib_configuration_api.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,12 @@ Logging
5252

5353
.. autofunction:: set_loglevel
5454

55+
Colormaps
56+
=========
57+
58+
.. autodata:: colormaps
59+
:no-value:
60+
5561
Miscellaneous
5662
=============
5763

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
Colormaps registry
2+
------------------
3+
4+
Colormaps are now managed via `matplotlib.colormaps`, which is a
5+
`.ColormapRegistry`.
6+
7+
Colormaps can be obtained using item access::
8+
9+
import matplotlib as mpl
10+
cmap = mpl.colormaps['viridis']
11+
12+
To register new colormaps use::
13+
14+
mpl.colormaps.register(my_colormap)
15+
16+
The use of `matplotlib.cm.get_cmap` and `matplotlib.cm.register_cmap` is
17+
discouraged in favor of the above. Within `.pyplot` the use of
18+
``plt.get_cmap()`` and ``plt.register_cmap()`` will continue to be supported.

lib/matplotlib/__init__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1445,3 +1445,8 @@ def inner(ax, *args, data=None, **kwargs):
14451445
_log.debug('interactive is %s', is_interactive())
14461446
_log.debug('platform is %s', sys.platform)
14471447
_log.debug('loaded modules: %s', list(sys.modules))
1448+
1449+
1450+
# workaround: we must defer colormaps import to after loading rcParams, because
1451+
# colormap creation depends on rcParams
1452+
from matplotlib.cm import _colormaps as colormaps

lib/matplotlib/cm.py

Lines changed: 75 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
normalization.
1616
"""
1717

18-
from collections.abc import MutableMapping
18+
from collections.abc import Mapping, MutableMapping
1919

2020
import numpy as np
2121
from numpy import ma
@@ -91,13 +91,86 @@ def _warn_deprecated(self):
9191
)
9292

9393

94+
class ColormapRegistry(Mapping):
95+
r"""
96+
Container for colormaps that are known to Matplotlib by name.
97+
98+
The universal registry instance is `matplotlib.colormaps`. There should be
99+
no need for users to instantiate `.ColormapRegistry` themselves.
100+
101+
Read access uses a dict-like interface mapping names to `.Colormap`\s::
102+
103+
import matplotlib as mpl
104+
cmap = mpl.colormaps['viridis']
105+
106+
Returned `.Colormap`\s are copies, so that their modification does not
107+
change the global definition of the colormap.
108+
109+
Additional colormaps can be added via `.ColormapRegistry.register`::
110+
111+
mpl.colormaps.register(my_colormap)
112+
"""
113+
def __init__(self, cmaps):
114+
self._cmaps = cmaps
115+
116+
def __getitem__(self, item):
117+
try:
118+
return self._cmaps[item].copy()
119+
except KeyError:
120+
raise KeyError(f"{item!r} is not a known colormap name")
121+
122+
def __iter__(self):
123+
return iter(self._cmaps)
124+
125+
def __len__(self):
126+
return len(self._cmaps)
127+
128+
def __str__(self):
129+
return ('ColormapRegistry; available colormaps:\n' +
130+
', '.join(f"'{name}'" for name in self))
131+
132+
def register(self, cmap, *, name=None, force=False):
133+
"""
134+
Register a new colormap.
135+
136+
The colormap name can then be used as a string argument to any ``cmap``
137+
parameter in Matplotlib. It is also available in ``pyplot.get_cmap``.
138+
139+
The colormap registry stores a copy of the given colormap, so that
140+
future changes to the original colormap instance do not affect the
141+
registered colormap. Think of this as the registry taking a snapshot
142+
of the colormap at registration.
143+
144+
Parameters
145+
----------
146+
cmap : matplotlib.colors.Colormap
147+
The colormap to register.
148+
149+
name : str, optional
150+
The name for the colormap. If not given, ``cmap.name`` is used.
151+
152+
force: bool, default: False
153+
If False, a ValueError is raised if trying to overwrite an already
154+
registered name. True supports overwriting registered colormaps
155+
other than the builtin colormaps.
156+
"""
157+
name = name or cmap.name
158+
if name in self and not force:
159+
raise ValueError(
160+
f'A colormap named "{name}" is already registered.')
161+
register_cmap(name, cmap.copy())
162+
163+
94164
_cmap_registry = _gen_cmap_registry()
95165
globals().update(_cmap_registry)
96166
# This is no longer considered public API
97167
cmap_d = _DeprecatedCmapDictWrapper(_cmap_registry)
98168
__builtin_cmaps = tuple(_cmap_registry)
99169

100-
# Continue with definitions ...
170+
# public acces to the colormaps should be via `matplotlib.colormaps`. For now,
171+
# we still create the registry here, but that should stay an implementation
172+
# detail.
173+
_colormaps = ColormapRegistry(_cmap_registry)
101174

102175

103176
def register_cmap(name=None, cmap=None, *, override_builtin=False):

0 commit comments

Comments
 (0)