15
15
"""
16
16
17
17
from collections .abc import Mapping
18
+ import functools
18
19
19
20
import matplotlib as mpl
20
21
from matplotlib import _api , colors
21
22
# TODO make this warn on access
22
23
from matplotlib .colorizer import _ScalarMappable as ScalarMappable # noqa
23
24
from matplotlib ._cm import datad
24
25
from matplotlib ._cm_listed import cmaps as cmaps_listed
25
- from matplotlib ._cm_multivar import cmap_families as multivar_cmaps
26
- from matplotlib ._cm_bivar import cmaps as bivar_cmaps
26
+ from matplotlib ._cm_multivar import (
27
+ cmap_families as multivar_cmaps , cmap_init as _multivar_cmap_init )
28
+ from matplotlib ._cm_bivar import cmaps as bivar_cmaps , cmap_init as _bivar_cmap_init
27
29
28
30
29
31
_LUTSIZE = mpl .rcParams ['image.lut' ]
@@ -34,15 +36,6 @@ def _gen_cmap_registry():
34
36
Generate a dict mapping standard colormap names to standard colormaps, as
35
37
well as the reversed colormaps.
36
38
"""
37
- cmap_d = {** cmaps_listed }
38
- for name , spec in datad .items ():
39
- cmap_d [name ] = ( # Precache the cmaps at a fixed lutsize..
40
- colors .LinearSegmentedColormap (name , spec , _LUTSIZE )
41
- if 'red' in spec else
42
- colors .ListedColormap (spec ['listed' ], name )
43
- if 'listed' in spec else
44
- colors .LinearSegmentedColormap .from_list (name , spec , _LUTSIZE ))
45
-
46
39
# Register colormap aliases for gray and grey.
47
40
aliases = {
48
41
# alias -> original name
@@ -51,16 +44,30 @@ def _gen_cmap_registry():
51
44
'gist_yerg' : 'gist_yarg' ,
52
45
'Grays' : 'Greys' ,
53
46
}
54
- for alias , original_name in aliases .items ():
55
- cmap = cmap_d [original_name ].copy ()
56
- cmap .name = alias
57
- cmap_d [alias ] = cmap
47
+ cmap_d = {** cmaps_listed , ** datad , ** aliases }
48
+ # Reversed cmaps.
49
+ for name in list (cmap_d .keys ()):
50
+ cmap_d [f'{ name } _r' ] = name
51
+
52
+ def cmap_init (name , cmap_spec ):
53
+ if name in datad :
54
+ spec = cmap_spec
55
+ return ( # Precache the cmaps at a fixed lutsize..
56
+ colors .LinearSegmentedColormap (name , spec , _LUTSIZE )
57
+ if 'red' in spec else
58
+ colors .ListedColormap (spec ['listed' ], name )
59
+ if 'listed' in spec else
60
+ colors .LinearSegmentedColormap .from_list (name , spec , _LUTSIZE ))
61
+ if name in aliases :
62
+ cmap = cmap_init (cmap_spec , cmap_d [cmap_spec ]).copy ()
63
+ cmap .name = name
64
+ return cmap
65
+ if name .endswith ('_r' ):
66
+ # Generate reversed cmaps.
67
+ return cmap_init (cmap_spec , cmap_d [cmap_spec ]).reversed ()
68
+ return colors .ListedColormap (cmap_spec , name = name )
58
69
59
- # Generate reversed cmaps.
60
- for cmap in list (cmap_d .values ()):
61
- rmap = cmap .reversed ()
62
- cmap_d [rmap .name ] = rmap
63
- return cmap_d
70
+ return cmap_d , cmap_init
64
71
65
72
66
73
class ColormapRegistry (Mapping ):
@@ -87,12 +94,15 @@ class ColormapRegistry(Mapping):
87
94
from matplotlib import colormaps
88
95
list(colormaps)
89
96
"""
90
- def __init__ (self , cmaps ):
91
- self ._cmaps = cmaps
92
- self ._builtin_cmaps = tuple (cmaps )
97
+ def __init__ (self , cmaps , init_func ):
98
+ self ._cmaps = {name : None for name in cmaps }
99
+ self ._init_func = init_func
100
+ self ._builtin_cmaps = cmaps
93
101
94
102
def __getitem__ (self , item ):
95
103
cmap = _api .check_getitem (self ._cmaps , colormap = item , _error_cls = KeyError )
104
+ if cmap is None :
105
+ cmap = self ._cmaps [item ] = self ._init_func (item , self ._builtin_cmaps [item ])
96
106
return cmap .copy ()
97
107
98
108
def __iter__ (self ):
@@ -233,12 +243,11 @@ def get_cmap(self, cmap):
233
243
# public access to the colormaps should be via `matplotlib.colormaps`. For now,
234
244
# we still create the registry here, but that should stay an implementation
235
245
# detail.
236
- _colormaps = ColormapRegistry (_gen_cmap_registry ())
237
- globals ().update (_colormaps )
246
+ _colormaps = ColormapRegistry (* _gen_cmap_registry ())
238
247
239
- _multivar_colormaps = ColormapRegistry (multivar_cmaps )
248
+ _multivar_colormaps = ColormapRegistry (multivar_cmaps , _multivar_cmap_init )
240
249
241
- _bivar_colormaps = ColormapRegistry (bivar_cmaps )
250
+ _bivar_colormaps = ColormapRegistry (bivar_cmaps , _bivar_cmap_init )
242
251
243
252
244
253
def _ensure_cmap (cmap ):
@@ -268,3 +277,10 @@ def _ensure_cmap(cmap):
268
277
if cmap_name not in _colormaps :
269
278
_api .check_in_list (sorted (_colormaps ), cmap = cmap_name )
270
279
return mpl .colormaps [cmap_name ]
280
+
281
+
282
+ @functools .cache
283
+ def __getattr__ (name ):
284
+ if name in _colormaps ._builtin_cmaps :
285
+ return _colormaps [name ]
286
+ raise AttributeError (f"module 'matplotlib.cm' has no attribute { name !r} " )
0 commit comments