Calculate RGB value for a range of values to create heat map

前端 未结 4 1757
故里飘歌
故里飘歌 2020-12-04 13:01

I am trying to create a heat map with python. For this I have to assign an RGB value to every value in the range of possible values. I thought of changing the color from blu

4条回答
  •  离开以前
    2020-12-04 13:28

    Here's another way to do it that, while not as absolutely short as possible, is much more general since it hasn't been hardcoded for your specific set of colors. This means it can also be used to linearly interpolate a specified range of values over a variably-sized palette of arbitrary colors.

    Also note that colors could have been interpolated in other colorspaces giving results that may be more pleasing than in others. This is illustrated in the different results obtained from the two separate answers I submitted to a related question titled Range values to pseudocolor.

    import sys
    EPSILON = sys.float_info.epsilon  # Smallest possible difference.
    
    def convert_to_rgb(minval, maxval, val, colors):
        # "colors" is a series of RGB colors delineating a series of
        # adjacent linear color gradients between each pair.
        # Determine where the given value falls proportionality within
        # the range from minval->maxval and scale that fractional value
        # by the total number in the "colors" pallette.
        i_f = float(val-minval) / float(maxval-minval) * (len(colors)-1)
        # Determine the lower index of the pair of color indices this
        # value corresponds and its fractional distance between the lower
        # and the upper colors.
        i, f = int(i_f // 1), i_f % 1  # Split into whole & fractional parts.
        # Does it fall exactly on one of the color points?
        if f < EPSILON:
            return colors[i]
        else:  # Otherwise return a color within the range between them.
            (r1, g1, b1), (r2, g2, b2) = colors[i], colors[i+1]
            return int(r1 + f*(r2-r1)), int(g1 + f*(g2-g1)), int(b1 + f*(b2-b1))
    
    if __name__ == '__main__':
        minval, maxval = 1, 3
        steps = 10
        delta = float(maxval-minval) / steps
        colors = [(0, 0, 255), (0, 255, 0), (255, 0, 0)]  # [BLUE, GREEN, RED]
        print('  Val       R    G    B')
        for i in range(steps+1):
            val = minval + i*delta
            r, g, b = convert_to_rgb(minval, maxval, val, colors)
            print('{:.3f} -> ({:3d}, {:3d}, {:3d})'.format(val, r, g, b))
    

    Numeric output:

      Val       R    G    B
    1.000 -> (  0,   0, 255)
    1.200 -> (  0,  50, 204)
    1.400 -> (  0, 101, 153)
    1.600 -> (  0, 153, 101)
    1.800 -> (  0, 204,  50)
    2.000 -> (  0, 255,   0)
    2.200 -> ( 51, 203,   0)
    2.400 -> (102, 152,   0)
    2.600 -> (153, 101,   0)
    2.800 -> (203,  51,   0)
    3.000 -> (255,   0,   0)
    

    Here's the output visualized as a horizontal gradient:

    horizontal gradient generated with function in answer

提交回复
热议问题