10
10
.. _palettable: https://jiffyclub.github.io/palettable/
11
11
12
12
However, we often want to create or manipulate colormaps in Matplotlib.
13
- This can be done using the class `.ListedColormap` and a Nx4 numpy array of
14
- values between 0 and 1 to represent the RGBA values of the colormap. There
15
- is also a `.LinearSegmentedColormap` class that allows colormaps to be
16
- specified with a few anchor points defining segments, and linearly
17
- interpolating between the anchor points.
13
+ This can be done using the class `.ListedColormap` or
14
+ `.LinearSegmentedColormap`.
15
+ Seen from the outside, both colormap classes map values between 0 and 1 to
16
+ a bunch of colors. There are, however, slight differences, some of which are
17
+ shown in the following.
18
+
19
+ Before manually creating or manipulating colormaps, let us first see how we
20
+ can obtain colormaps and their colors from existing colormap classes.
21
+
18
22
19
23
Getting colormaps and accessing their values
20
24
============================================
21
25
22
26
First, getting a named colormap, most of which are listed in
23
- :doc:`/tutorials/colors/colormaps` requires the use of
24
- `.matplotlib.cm.get_cmap`, which returns a
25
- :class:`.matplotlib.colors.ListedColormap` object. The second argument gives
26
- the size of the list of colors used to define the colormap, and below we
27
- use a modest value of 12 so there are not a lot of values to look at.
27
+ :doc:`/tutorials/colors/colormaps`, may be done using
28
+ `.matplotlib.cm.get_cmap`, which returns a colormap object.
29
+ The second argument gives the size of the list of colors used to define the
30
+ colormap, and below we use a modest value of 8 so there are not a lot of
31
+ values to look at.
28
32
"""
29
33
30
34
import numpy as np
31
35
import matplotlib .pyplot as plt
32
36
from matplotlib import cm
33
37
from matplotlib .colors import ListedColormap , LinearSegmentedColormap
34
38
35
- viridis = cm .get_cmap ('viridis' , 12 )
39
+ viridis = cm .get_cmap ('viridis' , 8 )
36
40
print (viridis )
37
41
38
42
##############################################################################
42
46
print (viridis (0.56 ))
43
47
44
48
##############################################################################
49
+ # ListedColormap
50
+ # --------------
51
+ #
52
+ # `ListedColormap` s store their color values in a ``.colors`` attribute.
45
53
# The list of colors that comprise the colormap can be directly accessed using
46
54
# the ``colors`` property,
47
55
# or it can be accessed indirectly by calling ``viridis`` with an array
48
56
# of values matching the length of the colormap. Note that the returned list
49
57
# is in the form of an RGBA Nx4 array, where N is the length of the colormap.
50
58
51
59
print ('viridis.colors' , viridis .colors )
52
- print ('viridis(range(12 ))' , viridis (range (12 )))
53
- print ('viridis(np.linspace(0, 1, 12 ))' , viridis (np .linspace (0 , 1 , 12 )))
60
+ print ('viridis(range(8 ))' , viridis (range (8 )))
61
+ print ('viridis(np.linspace(0, 1, 8 ))' , viridis (np .linspace (0 , 1 , 8 )))
54
62
55
63
##############################################################################
56
64
# The colormap is a lookup table, so "oversampling" the colormap returns
57
65
# nearest-neighbor interpolation (note the repeated colors in the list below)
58
66
59
- print ('viridis(np.linspace(0, 1, 15))' , viridis (np .linspace (0 , 1 , 15 )))
67
+ print ('viridis(np.linspace(0, 1, 12))' , viridis (np .linspace (0 , 1 , 12 )))
68
+
69
+ ##############################################################################
70
+ # LinearSegmentedColormap
71
+ # -----------------------
72
+ # `LinearSegmentedColormap` s do not have a ``.colors`` attribute.
73
+ # However, one may still call the colormap with an integer array, or with a
74
+ # float array between 0 and 1.
75
+
76
+ copper = cm .get_cmap ('copper' , 8 )
77
+ print (copper )
78
+
79
+ print ('copper(range(8))' , copper (range (8 )))
80
+ print ('copper(np.linspace(0, 1, 8))' , copper (np .linspace (0 , 1 , 8 )))
60
81
61
82
##############################################################################
62
83
# Creating listed colormaps
63
84
# =========================
64
85
#
65
- # This is essential the inverse operation of the above where we supply a
66
- # Nx4 numpy array with all values between 0 and 1,
67
- # to `.ListedColormap` to make a new colormap. This means that
68
- # any numpy operations that we can do on a Nx4 array make carpentry of
69
- # new colormaps from existing colormaps quite straight forward.
86
+ # Creating a colormap is essentially the inverse operation of the above where
87
+ # we supply a list or array of color specifications to `.ListedColormap` to
88
+ # make a new colormap.
70
89
#
71
- # Suppose we want to make the first 25 entries of a 256-length "viridis"
72
- # colormap pink for some reason:
90
+ # Before continuing with the tutorial, let us define a helper function that
91
+ # takes one of more colormaps as input, creates some random data and applies
92
+ # the colormap(s) to an image plot of that dataset.
73
93
74
- viridis = cm .get_cmap ('viridis' , 256 )
75
- newcolors = viridis (np .linspace (0 , 1 , 256 ))
76
- pink = np .array ([248 / 256 , 24 / 256 , 148 / 256 , 1 ])
77
- newcolors [:25 , :] = pink
78
- newcmp = ListedColormap (newcolors )
79
94
80
-
81
- def plot_examples (cms ):
82
- """Helper function to plot two colormaps."""
95
+ def plot_examples (colormaps ):
96
+ """
97
+ Helper function to plot data with associated colormap.
98
+ """
83
99
np .random .seed (19680801 )
84
100
data = np .random .randn (30 , 30 )
85
-
86
- fig , axs = plt .subplots (1 , 2 , figsize = (6 , 3 ), constrained_layout = True )
87
- for [ax , cmap ] in zip (axs , cms ):
101
+ n = len (colormaps )
102
+ fig , axs = plt .subplots (1 , n , figsize = (n * 2 + 2 , 3 ),
103
+ constrained_layout = True , squeeze = False )
104
+ for [ax , cmap ] in zip (axs .flat , colormaps ):
88
105
psm = ax .pcolormesh (data , cmap = cmap , rasterized = True , vmin = - 4 , vmax = 4 )
89
106
fig .colorbar (psm , ax = ax )
90
107
plt .show ()
91
108
109
+
110
+ ##############################################################################
111
+ # In the simplest case we might type in a list of color names to create a
112
+ # colormap from those.
113
+
114
+ cmap = ListedColormap (["darkorange" , "gold" , "lawngreen" , "lightseagreen" ])
115
+ plot_examples ([cmap ])
116
+
117
+ ##############################################################################
118
+ # In fact, that list may contain any valid
119
+ # :doc:`matplotlib color specification </tutorials/colors/colors>`.
120
+ # Particularly useful for creating custom colormaps are Nx4 numpy arrays.
121
+ # Because with the variety of numpy operations that we can do on a such an
122
+ # array, carpentry of new colormaps from existing colormaps become quite
123
+ # straight forward.
124
+ #
125
+ # For example, suppose we want to make the first 25 entries of a 256-length
126
+ # "viridis" colormap pink for some reason:
127
+
128
+ viridis = cm .get_cmap ('viridis' , 256 )
129
+ newcolors = viridis (np .linspace (0 , 1 , 256 ))
130
+ pink = np .array ([248 / 256 , 24 / 256 , 148 / 256 , 1 ])
131
+ newcolors [:25 , :] = pink
132
+ newcmp = ListedColormap (newcolors )
133
+
92
134
plot_examples ([viridis , newcmp ])
93
135
94
136
##############################################################################
@@ -113,14 +155,14 @@ def plot_examples(cms):
113
155
114
156
##############################################################################
115
157
# Of course we need not start from a named colormap, we just need to create
116
- # the Nx4 array to pass to `.ListedColormap`. Here we create a
117
- # brown colormap that goes to white... .
158
+ # the Nx4 array to pass to `.ListedColormap`. Here we create a
159
+ # colormap that goes from brown (RGB: 90,40,40) to white (RGB: 255,255,255) .
118
160
119
161
N = 256
120
162
vals = np .ones ((N , 4 ))
121
163
vals [:, 0 ] = np .linspace (90 / 256 , 1 , N )
122
- vals [:, 1 ] = np .linspace (39 / 256 , 1 , N )
123
- vals [:, 2 ] = np .linspace (41 / 256 , 1 , N )
164
+ vals [:, 1 ] = np .linspace (40 / 256 , 1 , N )
165
+ vals [:, 2 ] = np .linspace (40 / 256 , 1 , N )
124
166
newcmp = ListedColormap (vals )
125
167
plot_examples ([viridis , newcmp ])
126
168
@@ -190,6 +232,27 @@ def plot_linearmap(cdict):
190
232
[1.0 , 1.0 , 1.0 ]]
191
233
plot_linearmap (cdict )
192
234
235
+ #############################################################################
236
+ # Directly creating a segmented colormap from a list
237
+ # --------------------------------------------------
238
+ #
239
+ # The above described is a very versatile approach, but admitedly a bit
240
+ # cumbersome to implement. For some basic cases, the use of
241
+ # `LinearSegmentedColormap.from_list` may be easier. This creates a segmented
242
+ # colormap with equal spacings from a supplied list of colors.
243
+
244
+ colors = ["darkorange" , "gold" , "lawngreen" , "lightseagreen" ]
245
+ cmap1 = LinearSegmentedColormap .from_list ("mycmap" , colors )
246
+
247
+ #############################################################################
248
+ # If desired, the nodes of the colormap can be given as numbers
249
+ # between 0 and 1. E.g. one could have the reddish part take more space in the
250
+ # colormap.
251
+
252
+ nodes = [0.0 , 0.4 , 0.8 , 1.0 ]
253
+ cmap2 = LinearSegmentedColormap .from_list ("mycmap" , list (zip (nodes , colors )))
254
+
255
+ plot_examples ([cmap1 , cmap2 ])
193
256
194
257
#############################################################################
195
258
#
0 commit comments