Skip to content

Commit 4024c25

Browse files
committed
new functions and checks to sort colormaps
1 parent c217600 commit 4024c25

2 files changed

Lines changed: 8429 additions & 8288 deletions

File tree

colormaps/matplotlib_cmaps.py

Lines changed: 150 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
import os
1+
from __future__ import annotations
2+
3+
import copy
4+
import sys
25
from typing import Callable
36

47
import matplotlib.colors as pltc
@@ -8,10 +11,109 @@
811
from plotpy.mathutils.colormap import (
912
DEFAULT_COLORMAPS,
1013
DEFAULT_COLORMAPS_PATH,
14+
CmapDictType,
1115
EditableColormap,
1216
save_colormaps,
1317
)
1418

19+
PERCEPTUALLY_UNIFORM_CMAPS = ["viridis", "plasma", "inferno", "magma", "cividis"]
20+
SEQUENTIAL_CMAPS = [
21+
"Greys",
22+
"Purples",
23+
"Blues",
24+
"Greens",
25+
"Oranges",
26+
"Reds",
27+
"YlOrBr",
28+
"YlOrRd",
29+
"OrRd",
30+
"PuRd",
31+
"RdPu",
32+
"BuPu",
33+
"GnBu",
34+
"PuBu",
35+
"YlGnBu",
36+
"PuBuGn",
37+
"BuGn",
38+
"YlGn",
39+
]
40+
SEQUENTIAL_CMAPS2 = [
41+
"binary",
42+
"gist_yarg",
43+
"gist_gray",
44+
"gray",
45+
"bone",
46+
"pink",
47+
"spring",
48+
"summer",
49+
"autumn",
50+
"winter",
51+
"cool",
52+
"Wistia",
53+
"hot",
54+
"afmhot",
55+
"gist_heat",
56+
"copper",
57+
]
58+
DIVERGING_CMAPS = [
59+
"PiYG",
60+
"PRGn",
61+
"BrBG",
62+
"PuOr",
63+
"RdGy",
64+
"RdBu",
65+
"RdYlBu",
66+
"RdYlGn",
67+
"Spectral",
68+
"coolwarm",
69+
"bwr",
70+
"seismic",
71+
]
72+
CYCLIC_CMAPS = ["twilight", "twilight_shifted", "hsv"]
73+
QUALITATIVE_CMAPS = [
74+
"Pastel1",
75+
"Pastel2",
76+
"Paired",
77+
"Accent",
78+
"Dark2",
79+
"Set1",
80+
"Set2",
81+
"Set3",
82+
"tab10",
83+
"tab20",
84+
"tab20b",
85+
"tab20c",
86+
]
87+
MISCELLANEOUS_CMAPS = [
88+
"flag",
89+
"prism",
90+
"ocean",
91+
"gist_earth",
92+
"terrain",
93+
"gist_stern",
94+
"gnuplot",
95+
"gnuplot2",
96+
"CMRmap",
97+
"cubehelix",
98+
"brg",
99+
"gist_rainbow",
100+
"rainbow",
101+
"jet",
102+
"turbo",
103+
"nipy_spectral",
104+
"gist_ncar",
105+
]
106+
107+
SORTED_MATPLOTLIB_COLORMAPS: list[str] = [
108+
*PERCEPTUALLY_UNIFORM_CMAPS,
109+
*SEQUENTIAL_CMAPS,
110+
*SEQUENTIAL_CMAPS2,
111+
*DIVERGING_CMAPS,
112+
*CYCLIC_CMAPS,
113+
*QUALITATIVE_CMAPS,
114+
*MISCELLANEOUS_CMAPS,
115+
]
116+
15117

16118
def rgb_colors_to_hex_list(
17119
colors: list[tuple[int, int, int]]
@@ -112,15 +214,53 @@ def continuous_to_descrete_cmap(cmap: EditableColormap) -> EditableColormap:
112214
prev_pos, prev_color = raw_cmap[i]
113215
curr_pos, curr_color = pos, color
114216
new_pos = curr_pos * coeff
115-
print(curr_pos, new_pos, coeff)
116217
new_raw_cmap.append((new_pos, prev_color))
117218
new_raw_cmap.append((new_pos, curr_color))
118219
new_raw_cmap.append(raw_cmap[-1])
119220

120221
return EditableColormap.from_iterable(new_raw_cmap, name=cmap.name)
121222

122223

123-
def main():
224+
def sort_mpl_colormaps(colormaps: CmapDictType) -> CmapDictType:
225+
"""Filter and sort input colormaps to follow the same order (by category) as in the
226+
matplotlib colormaps documentation. Colormaps not found in the matplotlib
227+
are filtered out.
228+
229+
Args:
230+
colormaps: Dictionnary of colormaps to extract and order
231+
232+
Returns:
233+
Filtered and sorted colormaps dictionnary
234+
"""
235+
ordered_colormaps: CmapDictType = {}
236+
lower_cmap_names = [cm.lower() for cm in SORTED_MATPLOTLIB_COLORMAPS]
237+
for lower_name in lower_cmap_names:
238+
cmap = colormaps.get(lower_name, None)
239+
if lower_name.endswith("_r"):
240+
continue
241+
if cmap is None:
242+
print(f"Colormap {lower_name} not found in input colormaps.")
243+
continue
244+
ordered_colormaps[lower_name] = cmap
245+
return ordered_colormaps
246+
247+
248+
def append_non_mpl_colormaps(mpl_colormaps: CmapDictType, colormaps: CmapDictType):
249+
"""Append colormaps not found in the matplotlib colormaps to the input colormaps.
250+
Mutate the input in place.
251+
252+
Args:
253+
mpl_colormaps: dictionnary of matplotlib colormaps. Mutated in place.
254+
colormaps: dictionnary of colormaps to append to the matplotlib colormaps
255+
"""
256+
colormap_names = set(SORTED_MATPLOTLIB_COLORMAPS)
257+
for colormap in colormaps.values():
258+
if colormap.name not in colormap_names:
259+
print(f"{colormap} not in matplotlib colormaps.")
260+
mpl_colormaps[colormap.name.lower()] = colormap
261+
262+
263+
def main(cmaps: CmapDictType, out_json_path: str = DEFAULT_COLORMAPS_PATH):
124264

125265
new_cmaps: dict[str, list[tuple[float, str]]] = {}
126266

@@ -179,13 +319,14 @@ def main():
179319
new_cmaps[cm_name] = func_segmented_cmap_to_hex_list(n, cmap)
180320

181321
for name, raw_cm in new_cmaps.items():
182-
DEFAULT_COLORMAPS[name.lower()] = EditableColormap.from_iterable(
183-
raw_cm, name=name
184-
)
322+
cmaps[name.lower()] = EditableColormap.from_iterable(raw_cm, name=name)
185323

186-
json_file = os.path.join(os.path.dirname(__file__), "new_colormaps.json")
187-
save_colormaps(json_file, DEFAULT_COLORMAPS_PATH)
324+
ordered_cmaps = sort_mpl_colormaps(cmaps)
325+
append_non_mpl_colormaps(ordered_cmaps, cmaps)
326+
save_colormaps(out_json_path, ordered_cmaps)
188327

189328

190329
if __name__ == "__main__":
191-
main()
330+
cmaps = copy.deepcopy(DEFAULT_COLORMAPS)
331+
out_json = sys.argv[1] if len(sys.argv) > 1 else DEFAULT_COLORMAPS_PATH
332+
main(cmaps, out_json)

0 commit comments

Comments
 (0)