Here we have an interesting real-world algorithm requirement involving colors.
N
Pretty Colors: In order to draw a beautiful chart (i.e: pie chart) we need to pick a random set of N
colors that are "different enough" and look good together. This could be accomplished by fixing brightness and saturation and stepping through hue in steps of 360/N
. I think this algorithm, even if it looks quite ad-hoc, will be useful in more than one situation.
Any ideas?
Update: Eric is right that is impossible to guarantee the stability of colors for each label as new labels appear and disappear. But I'm happy if it is "stable enough", i.e. color changes are minimized.
I was thinking of something like:
2*N
) and try to 'round' the previous hue values to the new differentiated ones.But this leaves aside the issue of hard-coded colors.
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.