How to create colour gradient in Python?

Dipole picture Dipole · Sep 4, 2014 · Viewed 84.2k times · Source

I want to create a new colormap which interpolates between green and blue (or any other two colours for that matter). My goal is to get something like: gradient

First of all I am really not sure if this can be done using linear interpolation of blue and green. If it can, I'm not sure how to do so, I found some documentation on using a matplotlib method that interpolates specified RGB values here

The real trouble is understanding how "cdict2" works below. For the example the documentation says:

"Example: suppose you want red to increase from 0 to 1 over the bottom half, green to do the same over the middle half, and blue over the top half. Then you would use:"

from matplotlib import pyplot as plt
import matplotlib 
import numpy as np

plt.figure()
a=np.outer(np.arange(0,1,0.01),np.ones(10))
cdict2 = {'red':   [(0.0,  0.0, 0.0),
                   (0.5,  1.0, 1.0),
                   (1.0,  1.0, 1.0)],
         'green': [(0.0,  0.0, 0.0),
                   (0.25, 0.0, 0.0),
                   (0.75, 1.0, 1.0),
                   (1.0,  1.0, 1.0)],
         'blue':  [(0.0,  0.0, 0.0),
                   (0.5,  0.0, 0.0),
                   (1.0,  1.0, 1.0)]} 
my_cmap2 = matplotlib.colors.LinearSegmentedColormap('my_colormap2',cdict2,256)
plt.imshow(a,aspect='auto', cmap =my_cmap2)                   
plt.show()

EDIT: I now understand how the interpolation works, for example this will give a red to white interpolation:

White to red: Going down the columns of the "matrix" for each colour, in column one we have the xcoordinate of where we want the interpolation to start and end and the two other columns are the actual values for the colour value at that coordinate.

cdict2 = {'red':   [(0.0,  1.0, 1.0),
                    (1.0,  1.0, 1.0),
                    (1.0,  1.0, 1.0)],
         'green': [(0.0,  1.0, 1.0),
                   (1.0, 0.0, 0.0),
                   (1.0,  0.0, 0.0)],
     'blue':  [(0.0,  1.0, 1.0),
               (1.0,  0.0, 0.0),
               (1.0,  0.0, 0.0)]} 

It is evident that the gradient I want will be very difficult to create by interpolating in RGB space...

Answer

Hamy picture Hamy · Apr 19, 2015

A simple answer I have not seen yet is to just use the colour package.

Install via pip

pip install colour

Use as so:

from colour import Color
red = Color("red")
colors = list(red.range_to(Color("green"),10))

# colors is now a list of length 10
# Containing: 
# [<Color red>, <Color #f13600>, <Color #e36500>, <Color #d58e00>, <Color #c7b000>, <Color #a4b800>, <Color #72aa00>, <Color #459c00>, <Color #208e00>, <Color green>]

Change the inputs to any colors you want. As noted by @zelusp, this will not restrict itself to a smooth combination of only two colors (e.g. red to blue will have yellow+green in the middle), but based on the upvotes it's clear a number of folks find this to be a useful approximation