Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
255 views
in Technique[技术] by (71.8m points)

python - Range values to pseudocolor

I have a certain array of floats (in Python) that might range from 0 to 100. I want to create a pseudo-color image so that the colors vary from green (corresponding to 0) to red (100). This is similar to pcolor from matplotlib. However, I do not want to use pcolor.

Is there a function like pseudocolorForValue(val,(minval,maxval)) which returns an RGB triple corresponding to the pseudo-color value for val? Also, is there a flexibility in this function to choose whether to display colors from green-to-red or from red-to-green?

Thanks, Nik

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You could write your own function that converted the values 0…100 → 0…120 degrees and then used that value as the H (or angle) of a color in the HSV (or HLS) colorspace. This could then be converted into an RGB color for display purposes. Linearly interpreted colors often look better when they're calculated in this colorspace: Here's what HSV colorspace looks like:

hsv colorspace diagram

Update:

Good news, I was pleasantly surprised to discover that Python has colorspace conversion routines in its built-in colorsys module (they really mean "batteries included"). What's nice about that is that it makes creating a function that does what I described fairly easy, as illustrated below:

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       R      G      B')
    for val in range(0, 100+steps, steps):
        print('{:3d} -> ({:.3f}, {:.3f}, {:.3f})'.format(
                                                val, *pseudocolor(val, 0, 100)))

Output:

val       R      G      B
  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)

Here's a sample showing what its output looks like:

sample showing color interpolation in HSV colorspace

I think you may find the colors generated nicer than in my other answer.

Generalizing:

It's possible to modify this function to be a little more generic in the sense that it will work with colors other then just the Red and Green currently hardcoded into it.

Here's how to do that:

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       R      G      B')
    for val in range(0, 100+steps, steps):
        print('{:3d} -> ({:.3f}, {:.3f}, {:.3f})'.format(
                val, *pseudocolor(val, 0, 100, YELLOW, BLUE)))

Results:

sample showing color interpolation in HSV colorspace between yellow and blue


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...