反转颜色映射是可能的,如果
(a) 你知道它正在映射的数据范围并且
(b) 如果您知道已使用的颜色图,并且
(c) 如果颜色图明确。
以下函数将返回给定颜色、颜色图以及颜色图使用范围的值。
import numpy as np
import matplotlib.colors
import matplotlib.pyplot as plt
def get_value_from_cm(color, cmap, colrange=[0.,1.]):
color=matplotlib.colors.to_rgb(color)
r = np.linspace(colrange[0],colrange[1], 256)
norm = matplotlib.colors.Normalize(colrange[0],colrange[1])
mapvals = cmap(norm(r))[:,:3]
distance = np.sum((mapvals - color)**2, axis=1)
return r[np.argmin(distance)]
b = get_value_from_cm(plt.cm.coolwarm(0.5), plt.cm.coolwarm, [0.,1.])
c = get_value_from_cm(np.array([1,0,0]), plt.cm.coolwarm)
print b # 0.501960784314
print plt.cm.coolwarm(b)
# (0.86742763508627452, 0.86437659977254899, 0.86260246201960789, 1.0)
print plt.cm.coolwarm(0.5)
#(0.86742763508627452, 0.86437659977254899, 0.86260246201960789, 1.0)
请注意,此方法会产生错误,因此您只能从颜色图中获取最接近的值,而不是最初用于从地图创建颜色的值。
在问题的更新代码中,每个通道的颜色定义为 0 到 255 之间的整数。因此,您需要首先将它们映射到 0 到 1 的范围。
from PIL import Image
import numpy as np
import matplotlib
import matplotlib.cm as cm
values = [670, 894, 582, 103, 786, 348, 972, 718, 356, 692]
minima = 103
maxima = 972
norm = matplotlib.colors.Normalize(vmin=minima, vmax=maxima, clip=True)
mapper = cm.ScalarMappable(norm=norm, cmap=cm.gist_rainbow_r)
c = []
for i in range(10):
c.append(mapper.to_rgba(values[i], bytes=True))
print(c) # [(75, 255, 0, 255), (255, 77, 0, 255), (0, 255, 64, 255), (255, 0, 191, 255), (255, 250, 0, 255), (0, 72, 255, 255), (255, 0, 40, 255), (151, 255, 0, 255), (0, 83, 255, 255), (108, 255, 0, 255)]
def get_value_from_cm(color, cmap, colrange):
color = np.array(color)/255.
r = np.linspace(colrange[0], colrange[1], 256)
norm = matplotlib.colors.Normalize(colrange[0], colrange[1])
mapvals = cmap(norm(r))[:, :4] # there are 4 channels: r,g,b,a
distance = np.sum((mapvals - color) ** 2, axis=1)
return r[np.argmin(distance)]
decoded_colors = []
for i in range(10):
decoded_colors.append(get_value_from_cm(c[i], cm.gist_rainbow_r, colrange=[minima, maxima]))
print(decoded_colors)