Skip to content

Commit 49b8c4e

Browse files
committed
new script and save cmaps with caps
1 parent 5b9a24f commit 49b8c4e

2 files changed

Lines changed: 139 additions & 1 deletion

File tree

colormaps/matplotlib_cmaps.py

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
import os
2+
from typing import Callable
3+
4+
import matplotlib.colors as pltc
5+
import matplotlib.pyplot as plt
6+
import numpy as np
7+
8+
from plotpy.mathutils.colormap import (
9+
DEFAULT_COLORMAPS,
10+
DEFAULT_COLORMAPS_PATH,
11+
EditableColormap,
12+
save_colormaps,
13+
)
14+
15+
16+
def rgb_colors_to_hex_list(colors: list[tuple[int, int, int]]):
17+
return [(i / len(colors), pltc.to_hex(color)) for i, color in enumerate(colors)]
18+
19+
20+
def _interpolate(val, vmin, vmax):
21+
"""Interpolate a color component between to values as provided
22+
by matplotlib colormaps
23+
"""
24+
interp = (val - vmin[0]) / (vmax[0] - vmin[0])
25+
return (1 - interp) * vmin[1] + interp * vmax[2]
26+
27+
28+
def std_segmented_cmap_to_hex_list(cmdata: dict[str, list[tuple[float, float, float]]]):
29+
"""Setup a CustomQwtLinearColorMap according to
30+
matplotlib's data
31+
"""
32+
colors: list[tuple[float, str]] = []
33+
red = np.array(cmdata["red"])
34+
green = np.array(cmdata["green"])
35+
blue = np.array(cmdata["blue"])
36+
indices = sorted(set(red[:, 0]) | set(green[:, 0]) | set(blue[:, 0]))
37+
for i in indices:
38+
idxr = red[:, 0].searchsorted(i)
39+
idxg = green[:, 0].searchsorted(i)
40+
idxb = blue[:, 0].searchsorted(i)
41+
compr = _interpolate(i, red[idxr - 1], red[idxr])
42+
compg = _interpolate(i, green[idxg - 1], green[idxg])
43+
compb = _interpolate(i, blue[idxb - 1], blue[idxb])
44+
colors.append((i, pltc.to_hex((compr, compg, compb))))
45+
return colors
46+
47+
48+
InterpFuncT = Callable[[np.ndarray], np.ndarray]
49+
50+
51+
def func_segmented_cmap_to_hex_list(
52+
n: int,
53+
cmap: pltc.LinearSegmentedColormap,
54+
):
55+
colors = []
56+
arr = np.linspace(0, 1, n, dtype=float)
57+
colors = [(i, pltc.to_hex(rgba)) for i, rgba in zip(arr, cmap(arr))]
58+
return colors
59+
60+
61+
def interp_to_descrete_cmap(cmap: EditableColormap) -> EditableColormap:
62+
raw_cmap: tuple[tuple[float, str], ...] = cmap.to_tuples()
63+
new_raw_cmap: list[tuple[float, str]] = [raw_cmap[0]]
64+
n = len(raw_cmap)
65+
coeff = (n - 1) / n
66+
for i, (pos, color) in enumerate(raw_cmap[1:]):
67+
prev_pos, prev_color = raw_cmap[i]
68+
curr_pos, curr_color = pos, color
69+
new_pos = curr_pos * coeff
70+
print(curr_pos, new_pos, coeff)
71+
new_raw_cmap.append((new_pos, prev_color))
72+
new_raw_cmap.append((new_pos, curr_color))
73+
new_raw_cmap.append(raw_cmap[-1])
74+
75+
return EditableColormap.from_iterable(new_raw_cmap, name=cmap.name)
76+
77+
78+
def main():
79+
80+
new_cmaps: dict[str, list[tuple[float, str]]] = {}
81+
82+
cmaps_with_colors = [
83+
"magma",
84+
"viridis",
85+
"inferno",
86+
"plasma",
87+
"cividis",
88+
]
89+
90+
descrete_cmaps = [
91+
"Pastel1",
92+
"Pastel2",
93+
"Paired",
94+
"Accent",
95+
"Dark2",
96+
"Set1",
97+
"Set2",
98+
"Set3",
99+
]
100+
101+
cmaps_with_colors.extend(descrete_cmaps)
102+
103+
for cm_name in cmaps_with_colors:
104+
cmap = plt.get_cmap(cm_name)
105+
new_cmaps[cm_name] = rgb_colors_to_hex_list(cmap.colors)
106+
107+
for cm_name in descrete_cmaps:
108+
cmap = EditableColormap.from_iterable(new_cmaps[cm_name], name=cm_name)
109+
new_cmaps[cm_name] = list(interp_to_descrete_cmap(cmap).to_tuples())
110+
111+
segmented_cmaps = [
112+
"coolwarm",
113+
"bwr",
114+
"seismic",
115+
]
116+
117+
for cm_name in segmented_cmaps:
118+
cmap = plt.get_cmap(cm_name)
119+
new_cmaps[cm_name] = std_segmented_cmap_to_hex_list(cmap._segmentdata)
120+
121+
n = 128
122+
interp_cmaps = ["gnuplot2", "CMRmap", "rainbow", "turbo", "afmhot"]
123+
124+
for cm_name in interp_cmaps:
125+
cmap = plt.get_cmap(cm_name)
126+
new_cmaps[cm_name] = func_segmented_cmap_to_hex_list(n, cmap)
127+
128+
for name, raw_cm in new_cmaps.items():
129+
DEFAULT_COLORMAPS[name.lower()] = EditableColormap.from_iterable(
130+
raw_cm, name=name
131+
)
132+
133+
json_file = os.path.join(os.path.dirname(__file__), "new_colormaps.json")
134+
save_colormaps(json_file, DEFAULT_COLORMAPS_PATH)
135+
136+
137+
if __name__ == "__main__":
138+
main()

plotpy/mathutils/colormap.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ def save_colormaps(json_filename: str, colormaps: CmapDictType):
159159
json_filename: json file name/path in which to save the colormaps
160160
colormaps: Dictionnary of colormpas names -> CustomQwtLinearColormap
161161
"""
162-
raw_colormaps = {name: cmap.to_tuples() for name, cmap in colormaps.items()}
162+
raw_colormaps = {cmap.name: cmap.to_tuples() for cmap in colormaps.values()}
163163
json_abs_path = CONF.get_path(json_filename)
164164
with open(json_abs_path, "w", encoding="utf-8") as f:
165165
json.dump(raw_colormaps, f, indent=4)

0 commit comments

Comments
 (0)