Search code examples
pythonmappingrgb

How smoothly map a cost to a RBG 8x8x8 color?


i have a graph i want to visualize. I have nodes and edges, and to each edge is associated a cost. in order to visualize the cost of the edges, i would like to display them with shades of colors depending on how close each edge is to the maximum cost among all edges. What Im (stupidly) doing currently is something like this

 # Normalize cost of the particular edge in a [0,1] interval
        norm_cost = (edge_cost - min_cost) / (max_cost - min_cost)
        # Set colors based on cost
                    if norm_cost <= 0.1:
            edge_marker.color.r = 41 / 255
            edge_marker.color.g = 171 / 255  # dark green
            edge_marker.color.b = 67 / 255
        elif 0.1 < norm_cost <= 0.25:
            edge_marker.color.r = 43 / 255
            edge_marker.color.g = 209 / 255  # light green
            edge_marker.color.b = 65 / 255
        elif 0.25 < norm_cost <= 0.5:
            edge_marker.color.r = 255 / 255
            edge_marker.color.g = 255 / 255  # yellow
            edge_marker.color.b = 0 / 255
        elif 0.5 < norm_cost <= 0.75:
            edge_marker.color.r = 255 / 255
            edge_marker.color.g = 126 / 255  # orange
            edge_marker.color.b = 0 / 255
        elif 0.75 < norm_cost <= 1:
            edge_marker.color.r = 255 / 255
            edge_marker.color.g = 0 / 255  # red
            edge_marker.color.b = 0 / 255

What i would like to have is a smooth transition from dark green to red based on the the normalized cost, but i cant find a way to map in that specific way


Solution

  • Based on the concept of your color mapping, here is a diagram to control rgb values and the brightness, although the values are not same as your original code:

    enter image description here Then the code to generate the rgb values will look like:

    def torgb(c):
        if c < 0.25:
            v = c * 4
        else:
            v = 1
    
        if c < 0.5:
            r = 2 * v * c
            g = v
        else:
            r = v
            g = 2 * v * (1 - c)
    
        # clamp values between 0 and 1
        r = 1 if r > 1 else 0 if r < 0 else r
        g = 1 if g > 1 else 0 if g < 0 else g
        b = 0
    
        return r, g, b
    

    Here is the result of the color scale by changing norm_cost between 0 and 1: enter image description here