3sm1r
3sm1r

Reputation: 530

Create a function mapping a number in (0,1) to a color between blue and red

I want to create a function colfunc that receives as argument a number between 0 and 1 and returns a color between blue and red, where blue would correspond to a 0 and red to a 1. The ultimate goal is to do something like the following

from matplotlib import pyplot as plt
a=[1,2,3]
plt.plot(a,color=colfunc(0)) 

and it should plot a blue line or alternatively if I do

plt.plot(a,color=colfunc(1)) 

it should return a red line. This is straightforward, but then I also want to be able to do, for example,

plt.plot(a,color=colfunc(0.1))  

and it should return a line of the color of a tonality of purple that is closer to blue than to red and so on.

Upvotes: 0

Views: 1752

Answers (1)

martineau
martineau

Reputation: 123463

What you want to do is called Linear interpolation (sometimes abbreviated to "LERP"). In this case the interpolation is between to two colors in the RGB colorspace.

Here's how to use the pseudocolor() function in one answer of mine to the question Range values to pseudocolor to do what it sounds like you want. (I've renamed it colfunc() as per your question.)

def colfunc(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 one returned are
        composed of a sequence of N component values (e.g. RGB).
    """
    f = float(val-minval) / (maxval-minval)
    return tuple(f*(b-a)+a for (a, b) in zip(startcolor, stopcolor))


if __name__ == '__main__':
    RED, YELLOW, GREEN  = (1, 0, 0), (1, 1, 0), (0, 1, 0)
    CYAN, BLUE, MAGENTA = (0, 1, 1), (0, 0, 1), (1, 0, 1)
    steps = 10
    minval, maxval = 0.0, 1.0
    incr = (maxval-minval)/steps

    print('val       R      G      B')
    for i in range(steps+1):
        val = minval + round(i*incr, 1)
        print('{:.1f} -> ({:.3f}, {:.3f}, {:.3f})'.format(
                    val, *colfunc(val, minval, maxval, BLUE, RED)))

Output:

val       R      G      B
0.0 -> (0.000, 0.000, 1.000)
0.1 -> (0.100, 0.000, 0.900)
0.2 -> (0.200, 0.000, 0.800)
0.3 -> (0.300, 0.000, 0.700)
0.4 -> (0.400, 0.000, 0.600)
0.5 -> (0.500, 0.000, 0.500)
0.6 -> (0.600, 0.000, 0.400)
0.7 -> (0.700, 0.000, 0.300)
0.8 -> (0.800, 0.000, 0.200)
0.9 -> (0.900, 0.000, 0.100)
1.0 -> (1.000, 0.000, 0.000)

Here's a visualization showing the range of colors it will produce for different values within the minimum and maximum limits inclusively (such as 0.0–1.0):

visualization showing the range of colors from blue to red

Upvotes: 1

Related Questions