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

Skip to content

Commit b8e5ec0

Browse files
committed
Cache the color data to reduce startup time.
Also, cmap kwargs now accept colormap names as strings. svn path=/trunk/matplotlib/; revision=7311
1 parent 75ede62 commit b8e5ec0

File tree

4 files changed

+98
-139
lines changed

4 files changed

+98
-139
lines changed

CHANGELOG

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
2009-07-30 Add set_cmap and register_cmap, and improve get_cmap,
22
to provide convenient handling of user-generated
3-
colormaps. - EF
3+
colormaps. Reorganized _cm and cm modules, and added
4+
caching of the color data to reduce startup time. - EF
45

56
2009-07-28 Quiver speed improved, thanks to tip by Ray Speth. -EF
67

lib/matplotlib/_cm.py

Lines changed: 26 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,15 @@
11
"""
2-
Color data and pre-defined cmap objects.
2+
Nothing here but dictionaries for generating LinearSegmentedColormaps,
3+
and a dictionary of these dictionaries.
34
4-
This is a helper for cm.py, originally part of that file.
5-
Separating the data (this file) from cm.py makes both easier
6-
to deal with.
7-
8-
Objects visible in cm.py are the individual cmap objects ('autumn',
9-
etc.) and a dictionary, 'datad', including all of these objects.
105
"""
116

12-
import matplotlib as mpl
13-
import matplotlib.colors as colors
14-
LUTSIZE = mpl.rcParams['image.lut']
15-
167
_binary_data = {
178
'red' : ((0., 1., 1.), (1., 0., 0.)),
189
'green': ((0., 1., 1.), (1., 0., 0.)),
1910
'blue' : ((0., 1., 1.), (1., 0., 0.))
2011
}
2112

22-
2313
_bone_data = {'red': ((0., 0., 0.),(1.0, 1.0, 1.0)),
2414
'green': ((0., 0., 0.),(1.0, 1.0, 1.0)),
2515
'blue': ((0., 0., 0.),(1.0, 1.0, 1.0))}
@@ -379,44 +369,6 @@
379369
(1.0, 0.80, 0.80)]}
380370

381371

382-
autumn = colors.LinearSegmentedColormap('autumn', _autumn_data, LUTSIZE)
383-
bone = colors.LinearSegmentedColormap('bone ', _bone_data, LUTSIZE)
384-
binary = colors.LinearSegmentedColormap('binary ', _binary_data, LUTSIZE)
385-
cool = colors.LinearSegmentedColormap('cool', _cool_data, LUTSIZE)
386-
copper = colors.LinearSegmentedColormap('copper', _copper_data, LUTSIZE)
387-
flag = colors.LinearSegmentedColormap('flag', _flag_data, LUTSIZE)
388-
gray = colors.LinearSegmentedColormap('gray', _gray_data, LUTSIZE)
389-
hot = colors.LinearSegmentedColormap('hot', _hot_data, LUTSIZE)
390-
hsv = colors.LinearSegmentedColormap('hsv', _hsv_data, LUTSIZE)
391-
jet = colors.LinearSegmentedColormap('jet', _jet_data, LUTSIZE)
392-
pink = colors.LinearSegmentedColormap('pink', _pink_data, LUTSIZE)
393-
prism = colors.LinearSegmentedColormap('prism', _prism_data, LUTSIZE)
394-
spring = colors.LinearSegmentedColormap('spring', _spring_data, LUTSIZE)
395-
summer = colors.LinearSegmentedColormap('summer', _summer_data, LUTSIZE)
396-
winter = colors.LinearSegmentedColormap('winter', _winter_data, LUTSIZE)
397-
spectral = colors.LinearSegmentedColormap('spectral', _spectral_data, LUTSIZE)
398-
399-
400-
401-
datad = {
402-
'autumn': _autumn_data,
403-
'bone': _bone_data,
404-
'binary': _binary_data,
405-
'cool': _cool_data,
406-
'copper': _copper_data,
407-
'flag': _flag_data,
408-
'gray' : _gray_data,
409-
'hot': _hot_data,
410-
'hsv': _hsv_data,
411-
'jet' : _jet_data,
412-
'pink': _pink_data,
413-
'prism': _prism_data,
414-
'spring': _spring_data,
415-
'summer': _summer_data,
416-
'winter': _winter_data,
417-
'spectral': _spectral_data
418-
}
419-
420372
# 34 colormaps based on color specifications and designs
421373
# developed by Cynthia Brewer (http://colorbrewer.org).
422374
# The ColorBrewer palettes have been included under the terms
@@ -5859,48 +5811,26 @@
58595811
0.0078431377187371254, 0.0078431377187371254), (1.0,
58605812
0.0039215688593685627, 0.0039215688593685627)]}
58615813

5862-
Accent = colors.LinearSegmentedColormap('Accent', _Accent_data, LUTSIZE)
5863-
Blues = colors.LinearSegmentedColormap('Blues', _Blues_data, LUTSIZE)
5864-
BrBG = colors.LinearSegmentedColormap('BrBG', _BrBG_data, LUTSIZE)
5865-
BuGn = colors.LinearSegmentedColormap('BuGn', _BuGn_data, LUTSIZE)
5866-
BuPu = colors.LinearSegmentedColormap('BuPu', _BuPu_data, LUTSIZE)
5867-
Dark2 = colors.LinearSegmentedColormap('Dark2', _Dark2_data, LUTSIZE)
5868-
GnBu = colors.LinearSegmentedColormap('GnBu', _GnBu_data, LUTSIZE)
5869-
Greens = colors.LinearSegmentedColormap('Greens', _Greens_data, LUTSIZE)
5870-
Greys = colors.LinearSegmentedColormap('Greys', _Greys_data, LUTSIZE)
5871-
Oranges = colors.LinearSegmentedColormap('Oranges', _Oranges_data, LUTSIZE)
5872-
OrRd = colors.LinearSegmentedColormap('OrRd', _OrRd_data, LUTSIZE)
5873-
Paired = colors.LinearSegmentedColormap('Paired', _Paired_data, LUTSIZE)
5874-
Pastel1 = colors.LinearSegmentedColormap('Pastel1', _Pastel1_data, LUTSIZE)
5875-
Pastel2 = colors.LinearSegmentedColormap('Pastel2', _Pastel2_data, LUTSIZE)
5876-
PiYG = colors.LinearSegmentedColormap('PiYG', _PiYG_data, LUTSIZE)
5877-
PRGn = colors.LinearSegmentedColormap('PRGn', _PRGn_data, LUTSIZE)
5878-
PuBu = colors.LinearSegmentedColormap('PuBu', _PuBu_data, LUTSIZE)
5879-
PuBuGn = colors.LinearSegmentedColormap('PuBuGn', _PuBuGn_data, LUTSIZE)
5880-
PuOr = colors.LinearSegmentedColormap('PuOr', _PuOr_data, LUTSIZE)
5881-
PuRd = colors.LinearSegmentedColormap('PuRd', _PuRd_data, LUTSIZE)
5882-
Purples = colors.LinearSegmentedColormap('Purples', _Purples_data, LUTSIZE)
5883-
RdBu = colors.LinearSegmentedColormap('RdBu', _RdBu_data, LUTSIZE)
5884-
RdGy = colors.LinearSegmentedColormap('RdGy', _RdGy_data, LUTSIZE)
5885-
RdPu = colors.LinearSegmentedColormap('RdPu', _RdPu_data, LUTSIZE)
5886-
RdYlBu = colors.LinearSegmentedColormap('RdYlBu', _RdYlBu_data, LUTSIZE)
5887-
RdYlGn = colors.LinearSegmentedColormap('RdYlGn', _RdYlGn_data, LUTSIZE)
5888-
Reds = colors.LinearSegmentedColormap('Reds', _Reds_data, LUTSIZE)
5889-
Set1 = colors.LinearSegmentedColormap('Set1', _Set1_data, LUTSIZE)
5890-
Set2 = colors.LinearSegmentedColormap('Set2', _Set2_data, LUTSIZE)
5891-
Set3 = colors.LinearSegmentedColormap('Set3', _Set3_data, LUTSIZE)
5892-
Spectral = colors.LinearSegmentedColormap('Spectral', _Spectral_data, LUTSIZE)
5893-
YlGn = colors.LinearSegmentedColormap('YlGn', _YlGn_data, LUTSIZE)
5894-
YlGnBu = colors.LinearSegmentedColormap('YlGnBu', _YlGnBu_data, LUTSIZE)
5895-
YlOrBr = colors.LinearSegmentedColormap('YlOrBr', _YlOrBr_data, LUTSIZE)
5896-
YlOrRd = colors.LinearSegmentedColormap('YlOrRd', _YlOrRd_data, LUTSIZE)
5897-
gist_earth = colors.LinearSegmentedColormap('gist_earth', _gist_earth_data, LUTSIZE)
5898-
gist_gray = colors.LinearSegmentedColormap('gist_gray', _gist_gray_data, LUTSIZE)
5899-
gist_heat = colors.LinearSegmentedColormap('gist_heat', _gist_heat_data, LUTSIZE)
5900-
gist_ncar = colors.LinearSegmentedColormap('gist_ncar', _gist_ncar_data, LUTSIZE)
5901-
gist_rainbow = colors.LinearSegmentedColormap('gist_rainbow', _gist_rainbow_data, LUTSIZE)
5902-
gist_stern = colors.LinearSegmentedColormap('gist_stern', _gist_stern_data, LUTSIZE)
5903-
gist_yarg = colors.LinearSegmentedColormap('gist_yarg', _gist_yarg_data, LUTSIZE)
5814+
datad = {
5815+
'autumn': _autumn_data,
5816+
'bone': _bone_data,
5817+
'binary': _binary_data,
5818+
'cool': _cool_data,
5819+
'copper': _copper_data,
5820+
'flag': _flag_data,
5821+
'gray' : _gray_data,
5822+
'hot': _hot_data,
5823+
'hsv': _hsv_data,
5824+
'jet' : _jet_data,
5825+
'pink': _pink_data,
5826+
'prism': _prism_data,
5827+
'spring': _spring_data,
5828+
'summer': _summer_data,
5829+
'winter': _winter_data,
5830+
'spectral': _spectral_data
5831+
}
5832+
5833+
59045834
datad['Accent']=_Accent_data
59055835
datad['Blues']=_Blues_data
59065836
datad['BrBG']=_BrBG_data
@@ -5944,19 +5874,7 @@
59445874
datad['gist_stern']=_gist_stern_data
59455875
datad['gist_yarg']=_gist_yarg_data
59465876

5947-
# reverse all the colormaps.
5948-
# reversed colormaps have '_r' appended to the name.
5949-
5950-
def revcmap(data):
5951-
data_r = {}
5952-
for key, val in data.iteritems():
5953-
valnew = [(1.-a, b, c) for a, b, c in reversed(val)]
5954-
data_r[key] = valnew
5955-
return data_r
5956-
5957-
cmapnames = datad.keys()
5958-
for cmapname in cmapnames:
5959-
cmapname_r = cmapname+'_r'
5960-
cmapdat_r = revcmap(datad[cmapname])
5961-
datad[cmapname_r] = cmapdat_r
5962-
locals()[cmapname_r] = colors.LinearSegmentedColormap(cmapname_r, cmapdat_r, LUTSIZE)
5877+
5878+
5879+
5880+

lib/matplotlib/axes.py

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3911,12 +3911,12 @@ def legend(self, *args, **kwargs):
39113911
*bbox_to_anchor* keyword argument. bbox_to_anchor can be an instance
39123912
of BboxBase(or its derivatives) or a tuple of 2 or 4 floats.
39133913
For example,
3914-
3914+
39153915
loc = 'upper right', bbox_to_anchor = (0.5, 0.5)
39163916
39173917
will place the legend so that the upper right corner of the legend at
39183918
the center of the axes.
3919-
3919+
39203920
The legend location can be specified in other coordinate, by using the
39213921
*bbox_transform* keyword.
39223922
@@ -3946,7 +3946,7 @@ def legend(self, *args, **kwargs):
39463946
39473947
*fancybox*: [ None | False | True ]
39483948
if True, draw a frame with a round fancybox. If None, use rc
3949-
3949+
39503950
*shadow*: [ None | False | True ]
39513951
If *True*, draw a shadow behind legend. If *None*, use rc settings.
39523952
@@ -5172,9 +5172,9 @@ def scatter(self, x, y, s=20, c='b', marker='o', cmap=None, norm=None,
51725172
arguments will be used only if *c* is an array of floats.
51735173
51745174
*cmap*: [ None | Colormap ]
5175-
A :class:`matplotlib.colors.Colormap` instance. If *None*,
5176-
defaults to rc ``image.cmap``. *cmap* is only used if *c*
5177-
is an array of floats.
5175+
A :class:`matplotlib.colors.Colormap` instance or registered
5176+
name. If *None*, defaults to rc ``image.cmap``. *cmap* is
5177+
only used if *c* is an array of floats.
51785178
51795179
*norm*: [ None | Normalize ]
51805180
A :class:`matplotlib.colors.Normalize` instance is used to
@@ -5370,7 +5370,6 @@ def scatter(self, x, y, s=20, c='b', marker='o', cmap=None, norm=None,
53705370

53715371
if colors is None:
53725372
if norm is not None: assert(isinstance(norm, mcolors.Normalize))
5373-
if cmap is not None: assert(isinstance(cmap, mcolors.Colormap))
53745373
collection.set_array(np.asarray(c))
53755374
collection.set_cmap(cmap)
53765375
collection.set_norm(norm)
@@ -5712,7 +5711,6 @@ def hexbin(self, x, y, C = None, gridsize = 100, bins = None,
57125711
accum = bins.searchsorted(accum)
57135712

57145713
if norm is not None: assert(isinstance(norm, mcolors.Normalize))
5715-
if cmap is not None: assert(isinstance(cmap, mcolors.Colormap))
57165714
collection.set_array(accum)
57175715
collection.set_cmap(cmap)
57185716
collection.set_norm(norm)
@@ -6245,7 +6243,6 @@ def imshow(self, X, cmap=None, norm=None, aspect=None,
62456243
if not self._hold: self.cla()
62466244

62476245
if norm is not None: assert(isinstance(norm, mcolors.Normalize))
6248-
if cmap is not None: assert(isinstance(cmap, mcolors.Colormap))
62496246
if aspect is None: aspect = rcParams['image.aspect']
62506247
self.set_aspect(aspect)
62516248
im = mimage.AxesImage(self, cmap, norm, interpolation, origin, extent,
@@ -6490,7 +6487,6 @@ def pcolor(self, *args, **kwargs):
64906487
collection.set_alpha(alpha)
64916488
collection.set_array(C)
64926489
if norm is not None: assert(isinstance(norm, mcolors.Normalize))
6493-
if cmap is not None: assert(isinstance(cmap, mcolors.Colormap))
64946490
collection.set_cmap(cmap)
64956491
collection.set_norm(norm)
64966492
if vmin is not None or vmax is not None:
@@ -6612,7 +6608,6 @@ def pcolormesh(self, *args, **kwargs):
66126608
collection.set_alpha(alpha)
66136609
collection.set_array(C)
66146610
if norm is not None: assert(isinstance(norm, mcolors.Normalize))
6615-
if cmap is not None: assert(isinstance(cmap, mcolors.Colormap))
66166611
collection.set_cmap(cmap)
66176612
collection.set_norm(norm)
66186613
if vmin is not None or vmax is not None:
@@ -6719,7 +6714,6 @@ def pcolorfast(self, *args, **kwargs):
67196714
vmin = kwargs.pop('vmin', None)
67206715
vmax = kwargs.pop('vmax', None)
67216716
if norm is not None: assert(isinstance(norm, mcolors.Normalize))
6722-
if cmap is not None: assert(isinstance(cmap, mcolors.Colormap))
67236717

67246718
C = args[-1]
67256719
nr, nc = C.shape

lib/matplotlib/cm.py

Lines changed: 64 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,67 @@
11
"""
22
This module contains the instantiations of color mapping classes
33
"""
4+
import os
5+
6+
try:
7+
import cPickle as pickle
8+
except ImportError:
9+
import pickle
410

511
import numpy as np
612
from numpy import ma
713
import matplotlib as mpl
814
import matplotlib.colors as colors
915
import matplotlib.cbook as cbook
10-
from matplotlib._cm import *
1116

12-
# Dictionary for user-registered colormaps:
17+
LUTSIZE = mpl.rcParams['image.lut']
18+
19+
_cmcache = os.path.join(mpl.get_configdir(), 'colormaps.cache')
20+
21+
loaded = False
22+
try:
23+
c = open(_cmcache)
24+
datad = pickle.load(c)
25+
c.close()
26+
mpl.verbose.report("Using colormaps from %s" % _cmcache)
27+
loaded = True
28+
except:
29+
mpl.verbose.report("Could not load colormaps from %s" % _cmcache)
30+
31+
if not loaded:
32+
from matplotlib._cm import datad
33+
34+
try:
35+
c = open(_cmcache, 'w')
36+
pickle.dump(datad, c, 2)
37+
c.close()
38+
mpl.verbose.report("New colormap cache in %s" % _cmcache)
39+
except:
40+
mpl.verbose.report("Failed to generate colormap cache")
41+
1342
cmap_d = dict()
1443

15-
# Using this second dictionary allows us to handle any
16-
# Colormap instance; the built-in datad is only for
17-
# LinearSegmentedColormaps. The advantage of keeping
18-
# datad is that it delays the generation of the Colormap
19-
# instance until it is actually needed. Generating the
20-
# instance is fast enough, and typically done few enough
21-
# times, that there is no need to cache the result.
44+
# reverse all the colormaps.
45+
# reversed colormaps have '_r' appended to the name.
46+
47+
def revcmap(data):
48+
data_r = {}
49+
for key, val in data.iteritems():
50+
valnew = [(1.0-a, b, c) for a, b, c in reversed(val)]
51+
data_r[key] = valnew
52+
return data_r
53+
54+
_cmapnames = datad.keys() # need this list because datad is changed in loop
55+
for cmapname in _cmapnames:
56+
cmapname_r = cmapname+'_r'
57+
cmapdat_r = revcmap(datad[cmapname])
58+
datad[cmapname_r] = cmapdat_r
59+
cmap_d[cmapname] = colors.LinearSegmentedColormap(
60+
cmapname, datad[cmapname], LUTSIZE)
61+
cmap_d[cmapname_r] = colors.LinearSegmentedColormap(
62+
cmapname_r, cmapdat_r, LUTSIZE)
63+
64+
locals().update(cmap_d)
2265

2366
def register_cmap(name=None, cmap=None, data=None, lut=None):
2467
"""
@@ -67,6 +110,11 @@ def get_cmap(name=None, lut=None):
67110
68111
If *name* is a :class:`colors.Colormap` instance, it will be
69112
returned.
113+
114+
If *lut* is not None it must be an integer giving the number of
115+
entries desired in the lookup table, and *name* must be a
116+
standard mpl colormap name with a corresponding data dictionary
117+
in *datad*.
70118
"""
71119
if name is None:
72120
name = mpl.rcParams['image.cmap']
@@ -75,14 +123,12 @@ def get_cmap(name=None, lut=None):
75123
return name
76124

77125
if name in cmap_d:
78-
return cmap_d[name]
79-
80-
if name not in datad:
81-
raise ValueError("%s is not a known colormap name" % name)
82-
83-
if lut is None:
84-
lut = mpl.rcParams['image.lut']
85-
return colors.LinearSegmentedColormap(name, datad[name], lut)
126+
if lut is None:
127+
return cmap_d[name]
128+
elif name in datad:
129+
return colors.LinearSegmentedColormap(name, datad[name], lut)
130+
else:
131+
raise ValueError("Colormap %s is not recognized" % name)
86132

87133
class ScalarMappable:
88134
"""
@@ -105,7 +151,7 @@ def __init__(self, norm=None, cmap=None):
105151

106152
self._A = None
107153
self.norm = norm
108-
self.cmap = cmap
154+
self.cmap = get_cmap(cmap)
109155
self.colorbar = None
110156
self.update_dict = {'array':False}
111157

0 commit comments

Comments
 (0)