Algorithm For Generating Unique Colors

27,976

Solution 1

Does the number of possible elements have a reasonable low bound? One quick and easy solution is to just store an array of color values using the ID of the item. That assumes that you have a relatively low amount of colors, and you're certain that you won't go above a certain number of items, however.

If you want to generate colors rather than use a list, one trick to make them have a consistent and decent look is to generate them using HSB. Pre-define a brightness and saturation, then base the hue value off some function of the ID (this can be a variety of things depending on how many IDs you plan to have, but multiplying the ID by some amount (and modding when it exceeds 255!) is a good rough approach. With this approach the colors will all "align" in terms of saturation and brightness but they'll each have a distinct color.

I'm a bit bored at work, so I whipped together a fast solution:

class HsbColor
{
    public int Hue { get; set; }
    public int Saturation { get; set; }
    public int Brightness { get; set; }

    public Color ToRGB
    {
        // left as exercise to the reader...
    }
}

public class Item
{


    public int Id { get; set; }
    private static const byte EXPECTED_MAX = 15;
    private static int HUE_FACTOR = 255 / EXPECTED_MAX;

    public HsbColor Color 
    {
       get {

         var color = new HsbColor() { Saturation = 175, Brightness = 175 };

         color.Hue = (Id * HUE_FACTOR) % 255;

         return color;
       }
    }
}

Solution 2

I've checked all the ways to do it, solving more than a few ways. And finally brute force with CIEde2000 and really, your best bet is just a static list. You can't get more than about 30 colors with good distinctness no matter what you do. Factor in color blindness and the lines of confusion, and you're really making something that is a hindrance. Use a lookup table and modify the data points with some other characteristics than just color.

max difference color palette

#000000
#00FF00
#0000FF
#FF0000
#01FFFE
#FFA6FE
#FFDB66
#006401
#010067
#95003A
#007DB5
#FF00F6
#FFEEE8
#774D00
#90FB92
#0076FF
#D5FF00
#FF937E
#6A826C
#FF029D
#FE8900
#7A4782
#7E2DD2
#85A900
#FF0056
#A42400
#00AE7E
#683D3B
#BDC6FF
#263400
#BDD393
#00B917
#9E008E
#001544
#C28C9F
#FF74A3
#01D0FF
#004754
#E56FFE
#788231
#0E4CA1
#91D0CB
#BE9970
#968AE8
#BB8800
#43002C
#DEFF74
#00FFC6
#FFE502
#620E00
#008F9C
#98FF52
#7544B1
#B500FF
#00FF78
#FF6E41
#005F39
#6B6882
#5FAD4E
#A75740
#A5FFD2
#FFB167
#009BFF
#E85EBE

Solution 3

You can multiply the id by the golden ratio (phi) to get a number 0 <= n < 1. All of the numbers you generate will tend to be evenly distributed.

PHI = (1 + sqrt(5))/2
n = id * PHI - floor(id * PHI) 

Then it's a matter of converting that number to a color, e.g.

hue = floor(n * 256)

Solution 4

I have written an article about this same topic:

How to Generate Random Colors Programmatically

Basically you can use the HSV color space, set a fixed Saturation and Value, and modify the Hue. When you know the number of colors you need, just split the Hue's range [0,1[ by this. If you do not know the number of required colors, you can still use the golden ratio to select colors from this space.

Solution 5

Graphic designers know that if a lot of colors are going to be used near each other in an information display, the colors should be relatively close to each other in color space. Small changes in saturation or hue are usually better than large jumps–when many colors are involved, the human eye actually finds it easier to assimilate information when color distances are not very great.

Also, don't forget that some of your users will be color blind. Since there are so many varieties of color blindness, it is hard to know what combinations to avoid. Maybe someone else can address this question?

Share:
27,976
Bridger Maxwell
Author by

Bridger Maxwell

Updated on July 16, 2022

Comments

  • Bridger Maxwell
    Bridger Maxwell almost 2 years

    I am looking for an algorithm that will generate a series of colors so that the colors will be as widely distributed as possible (so they won't easily be mixed up).

    I have a series of objects that have IDs that count up from 1. I would like to represent each of these with a different, aesthetically pleasing, color that won't get easily confused with its neighbors. The colors should not necessarily be random though. I would like to get the same color each time I input the same ID.

  • Cédric Guillemette
    Cédric Guillemette almost 15 years
    See my answer for a way to avoid predicting the EXPECTED_MAX and still get an even distribution.
  • Ohad Schneider
    Ohad Schneider over 13 years
  • Berty
    Berty over 7 years
    @philmccull i modified it to just generate 30 unique and as visually different colors by only changing the hue. jsfiddle.net/hCtc3/42
  • Timmmm
    Timmmm over 6 years
    Nice technique.