范围值pseudocolor
我有一个浮点数(在Python中),可能范围从0到100.我想创build一个伪彩色图像,以便颜色从绿色(对应于0)到红色(100)不等。 这与matplotlib中的pcolor类似。 但是,我不想使用pcolor。
是否有像pseudocolorForValue(val,(minval,maxval))这样的函数返回与“val”的伪色值对应的RGB三元组? 另外,这个function是否有灵活性来select从绿到红还是从红到绿的颜色?
谢谢,Nik
您可以编写自己的函数,将0 … 100 => 0 … 120度的值进行转换,然后将该值用作HSV(或HLS)色彩空间中颜色的H(或angular度)。 然后可以将其转换为RGB颜色用于显示目的。 线性解释的颜色在这个颜色空间中计算时往往看起来更好:以下是HSV颜色空间的样子:
更新:
好消息是,我惊喜地发现Python在其内置的colorsys
模块中colorsys
空间转换例程(他们的意思是“包含电池”)。 有什么好的是,它使创build一个function,做我所描述的很容易,如下所示:
from colorsys import hsv_to_rgb def pseudocolor(val, minval, maxval): """ Convert val in range minval..maxval to the range 0..120 degrees which correspond to the colors Red and Green in the HSV colorspace. """ h = (float(val-minval) / (maxval-minval)) * 120 # Convert hsv color (h,1,1) to its rgb equivalent. # Note: hsv_to_rgb() function expects h to be in the range 0..1 not 0..360 r, g, b = hsv_to_rgb(h/360, 1., 1.) return r, g, b if __name__ == '__main__': steps = 10 print('val RG B') for val in range(0, 100+steps, steps): print('{:3d} -> ({:.3f}, {:.3f}, {:.3f})'.format( val, *pseudocolor(val, 0, 100)))
输出:
val RGB 0 -> (1.000, 0.000, 0.000) 10 -> (1.000, 0.200, 0.000) 20 -> (1.000, 0.400, 0.000) 30 -> (1.000, 0.600, 0.000) 40 -> (1.000, 0.800, 0.000) 50 -> (1.000, 1.000, 0.000) 60 -> (0.800, 1.000, 0.000) 70 -> (0.600, 1.000, 0.000) 80 -> (0.400, 1.000, 0.000) 90 -> (0.200, 1.000, 0.000) 100 -> (0.000, 1.000, 0.000)
下面是一个示例,显示了它的输出结果:
我想你可能会发现比我的其他答案更好的颜色。
归纳:
可以修改这个函数,使其更具通用性,因为它可以和其他颜色一起工作,除了当前硬编码的红色和绿色。
以下是如何做到这一点:
def pseudocolor(val, minval, maxval, start_hue, stop_hue): """ Convert val in range minval..maxval to the range start_hue..stop_hue degrees in the HSV colorspace. """ h = (float(val-minval) / (maxval-minval)) * (stop_hue-start_hue) + start_hue # Convert hsv color (h,1,1) to its rgb equivalent. # Note: hsv_to_rgb() function expects h to be in the range 0..1 not 0..360 r, g, b = hsv_to_rgb(h/360, 1., 1.) return r, g, b if __name__ == '__main__': # angles of common colors in hsv colorspace RED, YELLOW, GREEN, CYAN, BLUE, MAGENTA = range(0, 360, 60) steps = 10 print('val RG B') for val in range(0, 100+steps, steps): print('{:3d} -> ({:.3f}, {:.3f}, {:.3f})'.format( val, *pseudocolor(val, 0, 100, YEllOW, BLUE)))
结果:
虽然在HLS或HSV色彩空间中可以说并不像内插H那样漂亮,但实现方法要简单得多,就是编写一个函数,将单个值映射成三个分量,对应于完全red (1,0,0)
以及RGB颜色空间中完全绿色(0,1,0)
。
这是我的意思:
def pseudocolor(val, minval, maxval): """ Convert value in the range minval...maxval to a color between red and green. """ f = float(val-minval) / (maxval-minval) r, g, b = 1-f, f, 0. return r, g, b if __name__ == '__main__': steps = 10 print('val RG B') for val in xrange(0, 100+steps, steps): print('{:3d} -> ({:.3f}, {:.3f}, {:.3f})'.format( val, *pseudocolor(val, 0, 100)))
输出:
val RGB 0 -> (1.000, 0.000, 0.000) 10 -> (0.900, 0.100, 0.000) 20 -> (0.800, 0.200, 0.000) 30 -> (0.700, 0.300, 0.000) 40 -> (0.600, 0.400, 0.000) 50 -> (0.500, 0.500, 0.000) 60 -> (0.400, 0.600, 0.000) 70 -> (0.300, 0.700, 0.000) 80 -> (0.200, 0.800, 0.000) 90 -> (0.100, 0.900, 0.000) 100 -> (0.000, 1.000, 0.000)
您可以根据需要将浮点r,g,b分量转换为0到255之间的整数。
下面是一个示例,显示了它的输出结果:
如果你想从绿色变为红色,只需在函数中反转r和g的计算。 没有太多的额外的努力,你可以概括这个概念,以允许任何两个给定的颜色之间的线性插值。
以下是如何做到这一点:
def pseudocolor(val, minval, maxval, startcolor, stopcolor): """ Convert value in the range minval...maxval to a color in the range startcolor to stopcolor. The colors passed and the the one returned are composed of a sequence of N component values. """ f = float(val-minval) / (maxval-minval) return tuple(f*(ba)+a for (a, b) in zip(startcolor, stopcolor)) if __name__ == '__main__': YEllOW, BLUE = (1, 1, 0), (0, 0, 1) steps = 10 print('val RG B') for val in range(0, 100+steps, steps): print('{:3d} -> ({:.3f}, {:.3f}, {:.3f})'.format( val, *pseudocolor(val, 0, 100, YEllOW, BLUE)))
使用提供的颜色的输出示例:
您可以直接访问matplolib内置的colormap ,这正是pcolor用来确定其颜色映射的。 每个映射在[0,1]范围内都有一个浮点数,并返回一个元素(R,G,B,A)中的[0,1]范围内的浮点数的四元组元素。 这里是一个函数的例子,它使用标准的jet
colormap返回一个RGBA元组:
from matplotlib import cm def pseudocolor(val, minval, maxmal): # Scale val to be in the range [0, 1] val = (val - minval) / (maxval - minval) # Return RGBA tuple from jet colormap return cm.jet(val) pseudocolor(20, 0, 100) # Returns: (0.0, 0.3, 1.0, 1.0) pseudocolor(80, 0, 100) # Returns: (1.0, 0.4074, 0.0, 1.0)
这将映射到下图中显示的颜色范围。
关于这种方法的一个方便的function是,通过将cm.jet
更改为cm.rainbow
, cm.nipy_spectral
, cm.Accent
等,您可以轻松切换到任何一个matplotlib颜色映射 。