views:

242

answers:

1

Here we have an interesting real-world algorithm requirement involving colors.

1) Nice random colors: In ordeeing to draw a beautifull chart (i.e: pie chart) we need to pick a random set of Colors that:

a) are different enought

b) Play nicely

Doesnt Look hard. For example u fix bright and saturation and divide hue in steps of 360/Num_sectors

2) Stable: given Pie1 with sectors with labes ('A','B','C') and Pie2 with sector with labels ('B','C','D'), will be nice if color('B',pie1)= color('B',pie2) and the same for 'C' and so on, so people don't get crazy when seeing similar updated charts, even if some sectors appear some dissapeared or the number of sectors changed. The label is the only stable thing.

3) hard-coded colors: the algorithm allows hardcoded label->color relationships as an input but stills doing a good work (1 & 2) for the rest of free labels.

I think this algorithm, even if it looks quite ad-hoc, will be usefull in more then one situation.

Any ideas?

Edit for Eric: you're right that is impossible to guarantee the stability of colors for each label as new labels appear and disappear. But I'm happy if is stable enought.

1.- the less labels change the color, the better

2.- the less the color change, the better

I was thinking in something like:

1.- every label gets a random hue value using hash(label)%360

2.- in order to guarantee that they are different enought, we divide the hue circle in a fixed amount of steps (i.e: 2*num_labels) and try to 'round' the previous hue values to the new differentiated ones

3.- in the case of different labels going to the same rounded hue value, we break the tie somehow and move the point somewhere else.

I'm not really sure how to consider the hardcoded colors then...

Thanks again Erik

+2  A: 

You can pick a set of random colors that look good together using a color wheel algorithm. Here's a related SO question with implementation guides, or google for many others.

You can use something like a hash of your labels as a starting point on the color wheel to ensure stability. This also satisfies 3. if you have an override mechanism to state that a specific label hash value should correspond to a specific starting point on the color wheel.

EDIT:

The color wheel lets you pick one master starting point (e.g. (hash(A) % 360) and ensure that two other colors (B, C) are "nice" when used together with A. B and C are determined by A. If you can later have a pie chart (B, Y, Z), B would be set as (hash(B) % 360) and would be different than it was in the (A, B, C) case.

If you can arbitrarily mix labels on pie charts, NO algorithm can ensure they will always look good together. Here's a simple proof:

Let A, B, C be selected so that they look good together.

Now let A appear with an arbitrary color Z

You can certainly pick some color for Z such that A and Z will clash.

You can only guarantee that a certain set of colors will look good together, and that picking the same set will reproduce the same colors.

You can use the hash of e.g. the first label as the starting point on the wheel (hash(A)) or you can combine the hashes (hash(A) + 31*hash(B) + 31*31*hash(C)). Multiplying by 31 (a prime number) is something from the Java world that helps ensure a better mathematical distribution when combining multiple hashes.

Eric J.
If we define color(label):= hsb(hash(label)%360, S, B) will work but how u guarantee that the hue is different enougt.On the other side, if u use a color wheel, what label is hashed and start the color wheel and whitch labels are just followers? Thanks for your answer
Olmo
@Olmo: See my edit.
Eric J.
thaks a lot Eric. I've change the question to community wiki so I can answer with a little bit more of space
Olmo