|
1 | 1 | '''
|
| 2 | +========================== |
| 3 | +Lightness of the colormaps |
| 4 | +========================== |
| 5 | +
|
2 | 6 | For each colormap, plot the lightness parameter L* from CIELAB colorspace
|
3 | 7 | along the y axis vs index through the colormap. Colormaps are examined in
|
4 | 8 | categories as in the original matplotlib gallery of colormaps.
|
5 | 9 | '''
|
6 | 10 |
|
7 |
| -from colormaps import cmaps |
8 | 11 | import numpy as np
|
| 12 | +import matplotlib as mpl |
9 | 13 | import matplotlib.pyplot as plt
|
10 | 14 | from matplotlib import cm
|
11 |
| -import matplotlib as mpl |
12 | 15 | from colorspacious import cspace_converter
|
| 16 | +from colormaps import cmaps # the colormaps, grouped by category |
13 | 17 |
|
14 | 18 | mpl.rcParams.update({'font.size': 12})
|
15 | 19 |
|
16 |
| -# indices to step through colormap |
| 20 | +# Number of colormap per subplot for particular cmap categories |
| 21 | +_DSUBS = {'Perceptually Uniform Sequential': 4, 'Sequential': 6, |
| 22 | + 'Sequential (2)': 6, 'Diverging': 6, 'Qualitative': 4, |
| 23 | + 'Miscellaneous': 6} |
| 24 | + |
| 25 | +# Spacing between the colormaps of a subplot |
| 26 | +_DC = {'Perceptually Uniform Sequential': 1.4, 'Sequential': 0.7, |
| 27 | + 'Sequential (2)': 1.4, 'Diverging': 1.4, 'Qualitative': 1.4, |
| 28 | + 'Miscellaneous': 1.4} |
| 29 | + |
| 30 | +# Indices to step through colormap |
17 | 31 | x = np.linspace(0.0, 1.0, 100)
|
18 | 32 |
|
19 | 33 | # Do plot
|
20 | 34 | for cmap_category, cmap_list in cmaps:
|
21 | 35 |
|
22 |
| - # Do subplots so that colormaps have enough space. 5 per subplot? |
23 |
| - dsub = 5 # number of colormaps per subplot |
24 |
| - if cmap_category == 'Diverging': # because has 12 colormaps |
25 |
| - dsub = 6 |
26 |
| - elif cmap_category == 'Sequential (2)': |
27 |
| - dsub = 6 |
28 |
| - elif cmap_category == 'Sequential': |
29 |
| - dsub = 7 |
30 |
| - nsubplots = int(np.ceil(len(cmap_list)/float(dsub))) |
31 |
| - |
32 |
| - fig = plt.figure(figsize=(7,2.6*nsubplots)) |
| 36 | + # Do subplots so that colormaps have enough space. |
| 37 | + # Default is 6 colormaps per subplot. |
| 38 | + dsub = _DSUBS.get(cmap_category, 6) |
| 39 | + nsubplots = int(np.ceil(len(cmap_list) / float(dsub))) |
33 | 40 |
|
34 |
| - for i, subplot in enumerate(range(nsubplots)): |
| 41 | + # squeeze=False to handle similarly the case of a single subplot |
| 42 | + fig, axes = plt.subplots(nrows=nsubplots, squeeze=False, |
| 43 | + figsize=(7, 2.6*nsubplots)) |
35 | 44 |
|
36 |
| - locs = [] # locations for text labels |
| 45 | + for i, ax in enumerate(axes.flat): |
37 | 46 |
|
38 |
| - ax = fig.add_subplot(nsubplots, 1, i+1) |
| 47 | + locs = [] # locations for text labels |
39 | 48 |
|
40 | 49 | for j, cmap in enumerate(cmap_list[i*dsub:(i+1)*dsub]):
|
41 | 50 |
|
42 |
| - # Get rgb values for colormap |
43 |
| - rgb = cm.get_cmap(cmap)(x)[np.newaxis,:,:3] |
44 |
| - |
45 |
| - # Get colormap in CAM02-UCS colorspace. We want the lightness. |
| 51 | + # Get RGB values for colormap and convert the colormap in |
| 52 | + # CAM02-UCS colorspace. lab[0, :, 0] is the lightness. |
| 53 | + rgb = cm.get_cmap(cmap)(x)[np.newaxis, :, :3] |
46 | 54 | lab = cspace_converter("sRGB1", "CAM02-UCS")(rgb)
|
47 | 55 |
|
48 |
| - # Plot colormap L values |
49 |
| - # Do separately for each category so each plot can be pretty |
50 |
| - # to make scatter markers change color along plot: |
| 56 | + # Plot colormap L values. Do separately for each category |
| 57 | + # so each plot can be pretty. To make scatter markers change |
| 58 | + # color along plot: |
51 | 59 | # http://stackoverflow.com/questions/8202605/matplotlib-scatterplot-colour-as-a-function-of-a-third-variable
|
52 |
| - if cmap_category=='Perceptually Uniform Sequential': |
53 |
| - dc = 1.15 # spacing between colormaps |
54 |
| - ax.scatter(x+j*dc, lab[0,:,0], c=x, cmap=cmap, |
55 |
| - s=300, linewidths=0.) |
56 |
| - if i==2: |
57 |
| - ax.axis([-0.1,4.1,0,100]) |
58 |
| - else: |
59 |
| - ax.axis([-0.1,4.7,0,100]) |
60 |
| - locs.append(x[-1]+j*dc) # store locations for colormap labels |
61 |
| - |
62 |
| - elif cmap_category=='Sequential': |
63 |
| - dc = 0.6 # spacing between colormaps |
| 60 | + |
| 61 | + if cmap_category == 'Sequential': |
64 | 62 | # These colormaps all start at high lightness but we want them
|
65 | 63 | # reversed to look nice in the plot, so reverse the order.
|
66 |
| - ax.scatter(x+j*dc, lab[0,::-1,0], c=x[::-1], cmap=cmap, |
67 |
| - s=300, linewidths=0.) |
68 |
| - if i==2: |
69 |
| - ax.axis([-0.1,4.1,0,100]) |
70 |
| - else: |
71 |
| - ax.axis([-0.1,4.7,0,100]) |
72 |
| - locs.append(x[-1]+j*dc) # store locations for colormap labels |
73 |
| - |
74 |
| - elif cmap_category=='Sequential (2)': |
75 |
| - dc = 1.15 |
76 |
| - ax.scatter(x+j*dc, lab[0,:,0], c=x, cmap=cmap, |
77 |
| - s=300, linewidths=0.) |
78 |
| - ax.axis([-0.1,7.0,0,100]) |
79 |
| - # store locations for colormap labels |
80 |
| - locs.append(x[-1]+j*dc) |
81 |
| - |
82 |
| - elif cmap_category=='Diverging': |
83 |
| - dc = 1.2 |
84 |
| - ax.scatter(x+j*dc, lab[0,:,0], c=x, cmap=cmap, |
85 |
| - s=300, linewidths=0.) |
86 |
| - ax.axis([-0.1,7.1,0,100]) |
87 |
| - # store locations for colormap labels |
88 |
| - locs.append(x[int(x.size/2.)]+j*dc) |
89 |
| - elif cmap_category=='Qualitative': |
90 |
| - dc = 1.3 |
91 |
| - ax.scatter(x+j*dc, lab[0,:,0], c=x, cmap=cmap, |
92 |
| - s=300, linewidths=0.) |
93 |
| - ax.axis([-0.1,6.3,0,100]) |
94 |
| - # store locations for colormap labels |
95 |
| - locs.append(x[int(x.size/2.)]+j*dc) |
96 |
| - |
97 |
| - elif cmap_category=='Miscellaneous': |
98 |
| - dc = 1.25 |
99 |
| - ax.scatter(x+j*dc, lab[0,:,0], c=x, cmap=cmap, |
100 |
| - s=300, linewidths=0.) |
101 |
| - ax.axis([-0.1,6.1,0,100]) |
102 |
| - # store locations for colormap labels |
103 |
| - locs.append(x[int(x.size/2.)]+j*dc) |
104 |
| - |
105 |
| - # Set up labels for colormaps |
106 |
| - ax.xaxis.set_ticks_position('top') |
107 |
| - ticker = mpl.ticker.FixedLocator(locs) |
108 |
| - ax.xaxis.set_major_locator(ticker) |
109 |
| - formatter = mpl.ticker.FixedFormatter(cmap_list[i*dsub:(i+1)*dsub]) |
110 |
| - ax.xaxis.set_major_formatter(formatter) |
111 |
| - labels = ax.get_xticklabels() |
112 |
| - for label in labels: |
113 |
| - label.set_rotation(60) |
| 64 | + y_ = lab[0, ::-1, 0] |
| 65 | + c_ = x[::-1] |
| 66 | + else: |
| 67 | + y_ = lab[0, :, 0] |
| 68 | + c_ = x |
| 69 | + |
| 70 | + dc = _DC.get(cmap_category, 1.4) # cmaps horizontal spacing |
| 71 | + ax.scatter(x + j*dc, y_, c=c_, cmap=cmap, s=300, linewidths=0.0) |
| 72 | + |
| 73 | + # Store locations for colormap labels |
| 74 | + if cmap_category in ('Perceptually Uniform Sequential', |
| 75 | + 'Sequential'): |
| 76 | + locs.append(x[-1] + j*dc) |
| 77 | + elif cmap_category in ('Diverging', 'Qualitative', |
| 78 | + 'Miscellaneous', 'Sequential (2)'): |
| 79 | + locs.append(x[int(x.size/2.)] + j*dc) |
| 80 | + |
| 81 | + # Set up the axis limits: |
| 82 | + # * the 1st subplot is used as a reference for the x-axis limits |
| 83 | + # * lightness values goes from 0 to 100 (y-axis limits) |
| 84 | + ax.set_xlim(axes[0, 0].get_xlim()) |
| 85 | + ax.set_ylim(0.0, 100.0) |
| 86 | + |
| 87 | + # Set up labels for colormaps |
| 88 | + ax.xaxis.set_ticks_position('top') |
| 89 | + ticker = mpl.ticker.FixedLocator(locs) |
| 90 | + ax.xaxis.set_major_locator(ticker) |
| 91 | + formatter = mpl.ticker.FixedFormatter(cmap_list[i*dsub:(i+1)*dsub]) |
| 92 | + ax.xaxis.set_major_formatter(formatter) |
| 93 | + ax.xaxis.set_tick_params(rotation=50) |
114 | 94 |
|
115 | 95 | ax.set_xlabel(cmap_category + ' colormaps', fontsize=14)
|
116 | 96 | fig.text(0.0, 0.55, 'Lightness $L^*$', fontsize=12,
|
117 | 97 | transform=fig.transFigure, rotation=90)
|
118 | 98 |
|
119 |
| - fig.tight_layout(h_pad=0.05, pad=1.5) |
| 99 | + fig.tight_layout(h_pad=0.0, pad=1.5) |
120 | 100 | plt.show()
|
0 commit comments