1515 normalization.
1616"""
1717
18+ from collections .abc import MutableMapping
1819import functools
1920
2021import numpy as np
@@ -49,7 +50,7 @@ def revcmap(data):
4950LUTSIZE = mpl .rcParams ['image.lut' ]
5051
5152
52- def _gen_cmap_d ():
53+ def _gen_cmap_registry ():
5354"""
5455 Generate a dict mapping standard colormap names to standard colormaps, as
5556 well as the reversed colormaps.
@@ -71,10 +72,48 @@ def _gen_cmap_d():
7172return cmap_d
7273
7374
74- _cmap_d = _gen_cmap_d ()
75- locals ().update (_cmap_d )
75+ class _DeprecatedCmapDictWrapper (MutableMapping ):
76+ """Dictionary mapping for deprecated _cmap_d access."""
77+
78+ def __init__ (self ,cmap_registry ):
79+ self ._cmap_registry = cmap_registry
80+
81+ def __delitem__ (self ,key ):
82+ self ._warn_deprecated ()
83+ self ._cmap_registry .__delitem__ (key )
84+
85+ def __getitem__ (self ,key ):
86+ self ._warn_deprecated ()
87+ return self ._cmap_registry .__getitem__ (key )
88+
89+ def __iter__ (self ):
90+ return self ._cmap_registry .__iter__ ()
91+
92+ def __len__ (self ):
93+ return self ._cmap_registry .__len__ ()
94+
95+ def __setitem__ (self ,key ,val ):
96+ self ._warn_deprecated ()
97+ self ._cmap_registry .__setitem__ (key ,val )
98+
99+ def get (self ,key ,default = None ):
100+ self ._warn_deprecated ()
101+ return self ._cmap_registry .get (key ,default )
102+
103+ def _warn_deprecated (self ):
104+ cbook .warn_deprecated (
105+ "3.3" ,
106+ message = "The global colormaps dictionary is no longer "
107+ "considered public API." ,
108+ alternative = "Please use register_cmap() and get_cmap() to "
109+ "access the contents of the dictionary."
110+ )
111+
112+
113+ _cmap_registry = _gen_cmap_registry ()
114+ locals ().update (_cmap_registry )
76115# This is no longer considered public API
77- cmap_d = _cmap_d
116+ cmap_d = _DeprecatedCmapDictWrapper ( _cmap_registry )
78117
79118
80119# Continue with definitions ...
@@ -99,6 +138,13 @@ def register_cmap(name=None, cmap=None, data=None, lut=None):
99138 and the resulting colormap is registered. Instead of this implicit
100139 colormap creation, create a `.LinearSegmentedColormap` and use the first
101140 case: ``register_cmap(cmap=LinearSegmentedColormap(name, data, lut))``.
141+
142+ Notes
143+ -----
144+ Registering a colormap stores a reference to the colormap object
145+ which can currently be modified and inadvertantly change the global
146+ colormap state. This behavior is deprecated and in Matplotlib 3.5
147+ the registered colormap will be immutable.
102148 """
103149cbook ._check_isinstance ((str ,None ),name = name )
104150if name is None :
@@ -109,7 +155,7 @@ def register_cmap(name=None, cmap=None, data=None, lut=None):
109155"Colormap" )from err
110156if isinstance (cmap ,colors .Colormap ):
111157cmap ._global = True
112- _cmap_d [name ]= cmap
158+ _cmap_registry [name ]= cmap
113159return
114160if lut is not None or data is not None :
115161cbook .warn_deprecated (
@@ -123,7 +169,7 @@ def register_cmap(name=None, cmap=None, data=None, lut=None):
123169lut = mpl .rcParams ['image.lut' ]
124170cmap = colors .LinearSegmentedColormap (name ,data ,lut )
125171cmap ._global = True
126- _cmap_d [name ]= cmap
172+ _cmap_registry [name ]= cmap
127173
128174
129175def get_cmap (name = None ,lut = None ):
@@ -133,15 +179,18 @@ def get_cmap(name=None, lut=None):
133179 Colormaps added with :func:`register_cmap` take precedence over
134180 built-in colormaps.
135181
182+ Notes
183+ -----
184+ Currently, this returns the global colormap object, which is deprecated.
185+ In Matplotlib 3.5, you will no longer be able to modify the global
186+ colormaps in-place.
187+
136188 Parameters
137189 ----------
138190 name : `matplotlib.colors.Colormap` or str or None, default: None
139- If a `.Colormap` instance, it will be returned.
140- Otherwise, the name of a colormap known to Matplotlib, which will
141- be resampled by *lut*. Currently, this returns the global colormap
142- object, which is deprecated. In Matplotlib 3.5, you will no longer be
143- able to modify the global colormaps in-place.
144- The default, None, means :rc:`image.cmap`.
191+ If a `.Colormap` instance, it will be returned. Otherwise, the name of
192+ a colormap known to Matplotlib, which will be resampled by *lut*. The
193+ default, None, means :rc:`image.cmap`.
145194 lut : int or None, default: None
146195 If *name* is not already a Colormap instance and *lut* is not None, the
147196 colormap will be resampled to have *lut* entries in the lookup table.
@@ -150,11 +199,11 @@ def get_cmap(name=None, lut=None):
150199name = mpl .rcParams ['image.cmap' ]
151200if isinstance (name ,colors .Colormap ):
152201return name
153- cbook ._check_in_list (sorted (_cmap_d ),name = name )
202+ cbook ._check_in_list (sorted (_cmap_registry ),name = name )
154203if lut is None :
155- return _cmap_d [name ]
204+ return _cmap_registry [name ]
156205else :
157- return _cmap_d [name ]._resample (lut )
206+ return _cmap_registry [name ]._resample (lut )
158207
159208
160209class ScalarMappable :