views:

81

answers:

2

Is there a good algorithm for generating colors for use in graphs such as line / pie / bar charts? Virtually all graphs have a built-in list of colors that they automatically assign to elements added to it. But sometimes you need to manually assign the colors yourself, and in that case you'll want to avoid manually inserting colors yourself which is time-consuming and will probably have bad results, whereas an algorithm could probably do it much better.

The colors generated should have the following properties:

  • Be easily differentiable from each other: as more and more elements are added the probability of confusion and miss-interpretation rises. Therefore it is important that the colors be as easily discernible from each other as possible, especially colors that are close to each other in the color list. Conflicts are acceptable, though obviously preferably avoided.

  • Contain classic colors first: when few elements are present in a graph, the red, blue, darkorange, green, gray colors should preferably come up first, and the less easily discernible ones after.

Currently I'm simply using a color list I found somewhere, and if I have more elements than the color list, the list is reused, resulting sometimes in color collisions.

$default_colors = array(
    "#4684ee", "#dc3912", "#ff9900", "#008000", "#666666",
    "#4942cc", "#cb4ac5", "#d6ae00", "#336699", "#dd4477",
    "#aaaa11", "#66aa00", "#888888", "#994499", "#dd5511",
    "#22aa99", "#999999", "#705770", "#109618", "#a32929",
);

Is there such a function out there? I've looked but my google-fu was not strong enough.

+1  A: 

Working with the HSV colour space is probably the way to go. Off the top of my head, here is a possible algorithm that you could modify to suit your tastes.

  • let N be the number of colours that you need
  • let v = ceil(N / 6) be the number of different values that will be used
  • let h = min(N, 6) be the number of different hues that will be used
  • use values
    1, 1-1/v, ..., 1 - (v-1)/v
    each with hues
    0, 1/h, ..., (h-1)/h

This gives you h*v different colours, samples the full-saturation colour space with a fairly even distribution, stays away from dark colours for as long as possible, and comes up with primary colours first.

If you need even more colours, you can incorporate saturation as well.

Thomas