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

Mitja nun at meyl.com
Thu Jun 17 10:33:15 CEST 2004

```Edvard Majakari <edvard+news at majakari.net>
(news:87r7sfy6zy.fsf at titan.staselog.com) wrote:
> "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.

That is "descrement h and s", of course.

>
> 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).

That's bluffing on my side again, but I'd leave saturation as it is, and
then make colors by equally distributing hues (as you already did), except
that with say 12 colors I'd make 3 sets, each of them with different VALUE,
and each of them with equally distributed hues.

Guess you found a description before, but the HSV model is very intuitive
and made with humans in mind. Hue is the actual color - red, green, blue,
violet, ... Intensity varies from 1 (very intensive, vivid color) to 0 (no
color at all, just grey). Value is brightness.

So with what I described above, you'd get say blue, darker blue, very dark
blue, red, darker red, etc. To get dark brown, you'd have to play around
with saturation a bit.

>
> # 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>\
> """

```