32

I want to generate a list of color specifications in the form of (r, g, b) tuples, that span the entire color spectrum with as many entries as I want. So for 5 entries I would want something like:

  • (0, 0, 1)
  • (0, 1, 0)
  • (1, 0, 0)
  • (1, 0.5, 1)
  • (0, 0, 0.5)

Of course, if there are more entries than combination of 0 and 1 it should turn to use fractions, etc. What would be the best way to do this?

tshepang
  • 11,360
  • 21
  • 88
  • 132
Sverre Rabbelier
  • 1,358
  • 2
  • 15
  • 22

5 Answers5

59

Use the HSV/HSB/HSL color space (three names for more or less the same thing). Generate N tuples equally spread in hue space, then just convert them to RGB.

Sample code:

import colorsys
N = 5
HSV_tuples = [(x*1.0/N, 0.5, 0.5) for x in range(N)]
RGB_tuples = map(lambda x: colorsys.hsv_to_rgb(*x), HSV_tuples)
kquinn
  • 10,119
  • 3
  • 34
  • 35
  • 2
    Cool, then using colorsys.hsv_to_rgb I get exactly what I need :). [colorsys.hsv_to_rgb(x*1.0/N, 0.5, 0.5) for x in range(N)]. – Sverre Rabbelier May 18 '09 at 09:46
  • 2
    if you want to use an index in `RGB_tuples`, in Python 3 you must make a `list` out of the `map`, which is a generator, simply by `list(map(lambda...))` – Walter Tross Oct 19 '19 at 09:38
  • 2
    in Python 3 you don't need `x*1.0/N`, `x/N` always produces a float result. To get an integer result you would need to do `x//N` – Walter Tross Oct 19 '19 at 11:04
  • those `0.5`s can be replaced by other values. HSV tuples are (hue, saturation, value) tuples, with all tuple elements in the range from 0 to 1, see https://en.wikipedia.org/wiki/HSL_and_HSV – Walter Tross Oct 19 '19 at 11:09
34

Color palettes are interesting. Did you know that the same brightness of, say, green, is perceived more intensely than, say, red? Have a look at http://poynton.ca/PDFs/ColorFAQ.pdf. If you would like to use preconfigured palettes, have a look at seaborn's palettes:

import seaborn as sns
palette = sns.color_palette(None, 3)

Generates 3 colors from the current palette.

serv-inc
  • 32,612
  • 9
  • 143
  • 165
  • IMHO this is better than the accepted answer because the colors in the palette are distinctive. The HSV method generates colors that are hard to tell apart. – Björn Lindqvist Nov 26 '19 at 23:02
  • Yes, I 100% agree! This is much more modular and concise than the method presented in the accepted answer. – Shounak Ray Aug 05 '20 at 16:01
  • The palettes generated by Seaborn look great. I just wish it didn't depend on Matplotlib, which is a beast. – Martin CR Dec 06 '20 at 10:50
  • An entire paper on nothing but color theory, but not a single color in the entire article! Impresive. – Sebastian Nov 26 '21 at 11:20
11

Following the steps of kquinn's and jhrf :)

For Python 3 it can be done the following way:

def get_N_HexCol(N=5):
    HSV_tuples = [(x * 1.0 / N, 0.5, 0.5) for x in range(N)]
    hex_out = []
    for rgb in HSV_tuples:
        rgb = map(lambda x: int(x * 255), colorsys.hsv_to_rgb(*rgb))
        hex_out.append('#%02x%02x%02x' % tuple(rgb))
    return hex_out
ceprio
  • 315
  • 2
  • 10
10

I created the following function based on kquinn's answer.

import colorsys

def get_N_HexCol(N=5):

    HSV_tuples = [(x*1.0/N, 0.5, 0.5) for x in xrange(N)]
    hex_out = []
    for rgb in HSV_tuples:
        rgb = map(lambda x: int(x*255),colorsys.hsv_to_rgb(*rgb))
        hex_out.append("".join(map(lambda x: chr(x).encode('hex'),rgb)))
    return hex_out
Community
  • 1
  • 1
jhrf
  • 930
  • 9
  • 17
  • I was searching for this (y). But in my case there was no much light after I saw adding them to form a spectrum. The output looks like this [Spectrum](https://postimg.org/image/qspiz6c4h/) I need to have some more brightness on it. – ln2khanal Aug 05 '16 at 14:55
  • The hsv space is hue, saturation, value, so a saturation closer to 1 will make stronger colours and a value closer to 1 will higher the brightness. – C.Fe. Jun 22 '17 at 08:24
  • 1
    Anybody know the best way to update this to Py3? Something like: `hex_out.append("".join(list(map(lambda x: chr(x)[2:], rgb))))`? – kuanb Aug 12 '17 at 16:56
1

However many number of colors you need and very simple.

from matplotlib import cm
n_colors = 10
colours = cm.rainbow(np.linspace(0, 1, n_colors))
momo668
  • 93
  • 5