somewhat OT: function to produce n as distinct colors as possible

Edvard Majakari edvard+news at majakari.net
Wed Jun 16 09:20:17 EDT 2004


"Mitja" <nun at meyl.com> writes:

> I'd start with the HSI (aka HSL) model and distribute hues evenly. Don't
> know if that's the best solution what with all the stuff going on in our
> brain mangling our perception, but it should be close.
> Have a look at google for the HSI model and its conversion to RGB.

Thanks for the tip. After a little fiddling I ended up with a very simple
algorithm which uses hsv color model (hue, saturation and value). The
python module colorsys uses floats in the range [0..1.0], so I started
with all values at 1, and decrement h and v by step (1.0 / n, where n =
number of distinct colors) every turn. Note that I don't touch value
component.

I get quite nice values when n < 10. After that it gets worse, but at n =
20 colors it is still possible, if not easy, to separate a color from
another.

But the algorithm could be better for sure. For one thing, I don't see
dark brown anywhere, and it would be easy to separate from other colors
(even when n = 20).

# simple test for producing n different colors. Prints out a very simple
# (and probably not valid) web page with differently colored table cells.

import colorsys
import sys

def float2dec(color):
    return int(color*255)

def dec2hex_str(rgb):
    return "%06x" % (rgb[0]*256**2+rgb[1]*256+rgb[2])

def distinct_colors(n):
    colors = []
    step = 1.0/n
    h, s, v = (1, 1, 1)

    for i in range(n):
        r, g, b = map(float2dec, colorsys.hsv_to_rgb(h, s, v))
        colors.append((r, g, b))

        h, s, v = (h-step, s-step, v)

        if h < 0:
            h = 0
        if s < 0:
            s = 0
        if v < 0:
            v = 0

    return map(dec2hex_str, colors)

# main

color_count = int(sys.argv[1])

print """\
<html>
<title>%s</title>
<body>
<table>
\t<tr>\
""" % "Printing %d distinct colors" % color_count
i = 0
for color in distinct_colors(color_count):
    i += 1
    if i % 8 == 0:
        print '\t\t<td bgcolor="#%s">test area</td>\n\t</tr>\n\t<tr>' % color
    else:
        print '\t\t<td bgcolor="#%s">test area</td>' % color
print """\
\t</tr>
</table>
</body>
</html>\
"""
--
# Edvard Majakari		Software Engineer
# PGP PUBLIC KEY available    	Soli Deo Gloria!

"Debugging is twice as hard as writing the code in the firstplace. Therefore, if
 you  write the code as cleverly as possible, you are, by definition, not smart
 enough to debug it."  -- Brian W. Kernighan



More information about the Python-list mailing list