简体   繁体   English

如何在matplotlib的Colormap中解码颜色映射?

[英]How to decode color mapping in matplotlib's Colormap?

I know how to map a number to a color from this post: Map values to colors in matplotlib 我从这篇文章中知道如何将数字映射到颜色:在matplotlib中将值映射到颜色

But I don't know how to decode the mapping to get my original color, assuming this is a one-to-one mapping, which it must be I figure. 但是我不知道如何解码映射以获取我的原始颜色,假设这是一对一的映射,我必须确定。

I am encoding an image for visualization purposes, but I need to be able to decode it and read the original data values. 我正在对图像进行编码以用于可视化目的,但是我需要能够对其进行解码并读取原始数据值。

For reference, here are the Colormap docs: http://matplotlib.org/api/cm_api.html 作为参考,这里是Colormap文档: http : //matplotlib.org/api/cm_api.html

Here's my try to the main answer below, which still isn't working right. 这是我对以下主要答案的尝试,但仍无法正常工作。

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 = matplotlib.colors.to_rgba(color)
    r = np.linspace(colrange[0], colrange[1], 10) # there are 10 values
    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) # [778.88888888888891, 778.88888888888891, 489.22222222222223, 103.0, 778.88888888888891, 392.66666666666669, 103.0, 778.88888888888891, 392.66666666666669, 778.88888888888891]

Inverting the colormapping is possible, if 如果有可能反转颜色映射
(a) you know the data range it is mapping and (a)您知道它正在映射的数据范围,并且
(b) if you know the colormap that has been used, and (b)如果您知道已使用的颜色图,并且
(c) if the colormap is unambiguous. (c)颜色图是否明确。

The following function would return the value given a color, a colormap and the range over which the colormap has been used. 以下函数将返回给定颜色,色彩图和使用色彩图的范围的值。

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)

Note that this method involves an error, so you only get the closest value from the colormap and not the value that has initially been used to create the color from the map. 请注意,此方法涉及一个错误,因此您只能从颜色图中获得最接近的值,而不是最初用于从颜色图中创建颜色的值。

In the updated code from the question, you have the color defined as integers between 0 and 255 for each channel. 在问题的更新代码中,每个通道的颜色定义为0到255之间的整数。 You therefore need to first map those to the range 0 to 1. 因此,您需要首先将它们映射到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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM