Matplotlib:从具体值和相应的颜色创建一个连续的颜色条
Matplotlib: Create a continous colorbar from concrete values and corresponding colors
目标是根据具体的值和 RGB 颜色对创建连续的颜色图。
示例:
values = [1, 5, 10, 20]
colors = [(3, 40, 252), (252, 3, 20), (252, 223, 3), (35, 224, 13)]
假设我想获取值 15 的颜色,检索到的颜色将是 (252, 223, 3) 和 (35, 224, 13) 的混合色。在我的例子中,颜色是 (143, 223, 8)。我想为 1 到 20 之间的值获取正确的颜色。
您可以运行此代码获取计算颜色:
import matplotlib as mpl
import numpy as np
colors_zero_one = np.array([[252, 223, 3], [35, 224, 13]]) / 255
cmap = mpl.colors.LinearSegmentedColormap.from_list('custom', colors_zero_one, N=256)
norm = mpl.colors.Normalize(vmin=10, vmax=20)
print((np.array(cmap(norm(15))) * 255).astype(int))
我的想法是生成多个颜色图和规范并将它们合并为一个。但这只是一个广泛的想法。
有人知道如何解决这个任务吗?任何帮助表示赞赏
到目前为止我发现的所有内容都使用离散颜色,而不是连续过渡。
LinearSegmentedColormap.from_list(...)
接受元组列表。元组的第一个组件是从 0 到 1 的值,第二个组件是相应的颜色。您可以从标准化值创建这些:
from matplotlib import pyplot as plt
from matplotlib.colors import LinearSegmentedColormap
import numpy as np
values = [1, 5, 10, 20]
colors = [(3, 40, 252), (252, 3, 20), (252, 223, 3), (35, 224, 13)]
norm = plt.Normalize(min(values), max(values))
cmap = LinearSegmentedColormap.from_list(
'', [(norm(value), tuple(np.array(color) / 255)) for value, color in zip(values, colors)])
all_values = np.arange(values[0], values[-1] + 1)
for val in all_values:
print(f'{val}: {np.round(np.array(cmap(norm(val))) * 255).astype(int)}')
结果值:
1: [ 3 40 252 255]
2: [ 63 31 196 255]
3: [124 22 140 255]
4: [189 12 79 255]
5: [249 3 23 255]
6: [252 47 17 255]
7: [252 89 13 255]
8: [252 135 10 255]
9: [252 178 6 255]
10: [252 223 3 255]
11: [231 223 4 255]
12: [208 223 5 255]
13: [187 223 6 255]
14: [164 223 7 255]
15: [143 224 8 255]
16: [121 224 9 255]
17: [100 224 10 255]
18: [ 77 224 11 255]
19: [ 56 224 12 255]
20: [ 35 224 13 255]
这是一个可视化:
import seaborn as sns
plt.figure(figsize=(5, 12))
ax = sns.heatmap(all_values.reshape(-1, 1), xticklabels=[], yticklabels=all_values,
annot=[[f'{tuple(np.round(np.array(cmap(norm(val))) * 255)[:3].astype(int))}'] for val in all_values],
fmt='', cmap=cmap, norm=norm, lw=2,
cbar_kws={'ticks': range(values[0], values[-1] + 1)})
ax.invert_yaxis()
ax.tick_params(labelrotation=0)
plt.show()
目标是根据具体的值和 RGB 颜色对创建连续的颜色图。
示例:
values = [1, 5, 10, 20]
colors = [(3, 40, 252), (252, 3, 20), (252, 223, 3), (35, 224, 13)]
假设我想获取值 15 的颜色,检索到的颜色将是 (252, 223, 3) 和 (35, 224, 13) 的混合色。在我的例子中,颜色是 (143, 223, 8)。我想为 1 到 20 之间的值获取正确的颜色。
您可以运行此代码获取计算颜色:
import matplotlib as mpl
import numpy as np
colors_zero_one = np.array([[252, 223, 3], [35, 224, 13]]) / 255
cmap = mpl.colors.LinearSegmentedColormap.from_list('custom', colors_zero_one, N=256)
norm = mpl.colors.Normalize(vmin=10, vmax=20)
print((np.array(cmap(norm(15))) * 255).astype(int))
我的想法是生成多个颜色图和规范并将它们合并为一个。但这只是一个广泛的想法。
有人知道如何解决这个任务吗?任何帮助表示赞赏
到目前为止我发现的所有内容都使用离散颜色,而不是连续过渡。
LinearSegmentedColormap.from_list(...)
接受元组列表。元组的第一个组件是从 0 到 1 的值,第二个组件是相应的颜色。您可以从标准化值创建这些:
from matplotlib import pyplot as plt
from matplotlib.colors import LinearSegmentedColormap
import numpy as np
values = [1, 5, 10, 20]
colors = [(3, 40, 252), (252, 3, 20), (252, 223, 3), (35, 224, 13)]
norm = plt.Normalize(min(values), max(values))
cmap = LinearSegmentedColormap.from_list(
'', [(norm(value), tuple(np.array(color) / 255)) for value, color in zip(values, colors)])
all_values = np.arange(values[0], values[-1] + 1)
for val in all_values:
print(f'{val}: {np.round(np.array(cmap(norm(val))) * 255).astype(int)}')
结果值:
1: [ 3 40 252 255]
2: [ 63 31 196 255]
3: [124 22 140 255]
4: [189 12 79 255]
5: [249 3 23 255]
6: [252 47 17 255]
7: [252 89 13 255]
8: [252 135 10 255]
9: [252 178 6 255]
10: [252 223 3 255]
11: [231 223 4 255]
12: [208 223 5 255]
13: [187 223 6 255]
14: [164 223 7 255]
15: [143 224 8 255]
16: [121 224 9 255]
17: [100 224 10 255]
18: [ 77 224 11 255]
19: [ 56 224 12 255]
20: [ 35 224 13 255]
这是一个可视化:
import seaborn as sns
plt.figure(figsize=(5, 12))
ax = sns.heatmap(all_values.reshape(-1, 1), xticklabels=[], yticklabels=all_values,
annot=[[f'{tuple(np.round(np.array(cmap(norm(val))) * 255)[:3].astype(int))}'] for val in all_values],
fmt='', cmap=cmap, norm=norm, lw=2,
cbar_kws={'ticks': range(values[0], values[-1] + 1)})
ax.invert_yaxis()
ax.tick_params(labelrotation=0)
plt.show()