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
8000
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
+ #####################
8000
#########################################################
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.
89
+ #
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.
93
+
94
+ def plot_examples (colormaps ):
95
+ """
96
+ Helper function to plot data with associated colormap.
97
+ """
98
+ np .random .seed (19680801 )
99
+ data = np .random .randn (30 , 30 )
100
+ n = len (colormaps )
101
+ fig , axs = plt .subplots (1 , n , figsize = (n * 2 + 2 , 3 ),
102
+ constrained_layout = True , squeeze = False )
103
+ for [ax , cmap ] in zip (axs .flat , colormaps ):
104
+ psm = ax .pcolormesh (data , cmap = cmap , rasterized = True , vmin = - 4 , vmax = 4 )
105
+ fig .colorbar (psm , ax = ax )
106
+ plt .show ()
107
+
108
+
109
+ ##############################################################################
110
+ # In the simplest case we might type in a list of color names to create a
111
+ # colormap from those.
112
+
113
+ cmap = ListedColormap (["darkorange" , "gold" , "lawngreen" , "lightseagreen" ])
114
+ plot_examples ([cmap ])
115
+
116
+ ##############################################################################
117
+ # In fact, that list may contain any valid
118
+ # :doc:`matplotlib color specification </tutorials/colors/colors>`.
119
+ # Particularly useful for creating custom colormaps are Nx4 numpy arrays.
120
+ # Because with the variety of numpy operations that we can do on a such an
121
+ # array, carpentry of new colormaps from existing colormaps become quite
122
+ # straight forward.
70
123
#
71
- # Suppose we want to make the first 25 entries of a 256-length "viridis"
72
- # colormap pink for some reason:
124
+ # For example, suppose we want to make the first 25 entries of a 256-length
125
+ # "viridis" colormap pink for some reason:
73
126
74
127
viridis = cm .get_cmap ('viridis' , 256 )
75
128
newcolors = viridis (np .linspace (0 , 1 , 256 ))
76
129
pink = np .array ([248 / 256 , 24 / 256 , 148 / 256 , 1 ])
77
130
newcolors [:25 , :] = pink
78
131
newcmp = ListedColormap (newcolors )
79
132
80
-
81
- def plot_examples (cms ):
82
- """Helper function to plot two colormaps."""
83
- np .random .seed (19680801 )
84
- 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 ):
88
- psm = ax .pcolormesh (data , cmap = cmap , rasterized = True , vmin = - 4 , vmax = 4 )
89
- fig .colorbar (psm , ax = ax )
90
- plt .show ()
91
-
92
133
plot_examples ([viridis , newcmp ])
93
134
94
135
##############################################################################
@@ -113,14 +154,14 @@ def plot_examples(cms):
113
154
114
155
##############################################################################
115
156
# 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... .
157
+ # the Nx4 array to pass to `.ListedColormap`. Here we create a
158
+ # colormap that goes from brown (RGB: 90,40,40) to white (RGB: 255,255,255) .
118
159
119
160
N = 256
120
161
vals = np .ones ((N , 4 ))
121
162
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 )
163
+ vals [:, 1 ] = np .linspace (40 / 256 , 1 , N )
164
+ vals [:, 2 ] = np .linspace (40 / 256 , 1 , N )
124
165
newcmp = ListedColormap (vals )
125
166
plot_examples ([viridis , newcmp ])
126
167
@@ -190,6 +231,27 @@ def plot_linearmap(cdict):
190
231
[1.0 , 1.0 , 1.0 ]]
191
232
plot_linearmap (cdict )
192
233
234
+ #############################################################################
235
+ # Directly creating a segmented colormap from a list
236
+ # --------------------------------------------------
237
+ #
238
+ # The above described is a very versatile approach, but admitedly a bit
239
+ # cumbersome to implement. For some basic cases, the use of
240
+ # `LinearSegmentedColormap.from_list` may be easier. This creates a segmented
241
+ # colormap with equal spacings from a supplied list of colors.
242
+
243
+ colors = ["darkorange" , "gold" , "lawngreen" , "lightseagreen" ]
244
+ cmap1 = LinearSegmentedColormap .from_list ("mycmap" , colors )
245
+
246
+ #############################################################################
247
+ # If desired, the nodes of the colormap can be given as numbers
248
+ # between 0 and 1. E.g. one could have the reddish part take more space in the
249
+ # colormap.
250
+
251
+ nodes = [0.0 , 0.4 , 0.8 , 1.0 ]
252
+ cmap2 = LinearSegmentedColormap .from_list ("mycmap" , list (zip (nodes , colors )))
253
+
254
+ plot_examples ([cmap1 , cmap2 ])
193
255
194
256
#############################################################################
195
257
#
0 commit comments