Generate distinctly different RGB colors in graphs
When generating graphs and showing different sets of data it usually a good idea to difference the sets by color. So one line is red and the next is green and so on. The problem is then that when the number of datasets is unknown one needs to randomly generate these colors and often they end up very close to each other (green, light green for example).
Any ideas on how this could be solved and how it would be possibler to generate distinctly different colors?
I'd be great if any examples (feel free to just discuss the problem and solution without examples if you find that easier) were in C# and RGB based colors.
You have three colour channels 0 to 255 R, G and B.
First go through
0, 0, 255
0, 255, 0
255, 0, 0
Then go through
0, 255, 255
255, 0, 255
255, 255, 0
Then divide by 2 => 128 and start again:
0, 0, 128
0, 128, 0
128, 0, 0
0, 128, 128
128, 0, 128
128, 128, 0
Divide by 2 => 64
Next time add 64 to 128 => 192
follow the pattern.
Straightforward to program and gives you fairly distinct colours.
EDIT: Request for code sample
Also - adding in the additional pattern as below if gray is an acceptable colour:
255, 255, 255
128, 128, 128
There are a number of ways you can handle generating these in code.
The Easy Way
If you can guarantee that you will never need more than a fixed number of colours, just generate an array of colours following this pattern and use those:
static string[] ColourValues = new string[] {
"FF0000", "00FF00", "0000FF", "FFFF00", "FF00FF", "00FFFF", "000000",
"800000", "008000", "000080", "808000", "800080", "008080", "808080",
"C00000", "00C000", "0000C0", "C0C000", "C000C0", "00C0C0", "C0C0C0",
"400000", "004000", "000040", "404000", "400040", "004040", "404040",
"200000", "002000", "000020", "202000", "200020", "002020", "202020",
"600000", "006000", "000060", "606000", "600060", "006060", "606060",
"A00000", "00A000", "0000A0", "A0A000", "A000A0", "00A0A0", "A0A0A0",
"E00000", "00E000", "0000E0", "E0E000", "E000E0", "00E0E0", "E0E0E0",
};
The Hard Way
If you don't know how many colours you are going to need, the code below will generate up to 896 colours using this pattern. (896 = 256 * 7 / 2) 256 is the colour space per channel, we have 7 patterns and we stop before we get to colours separated by only 1 colour value.
I've probably made harder work of this code than I needed to. First, there is an intensity generator which starts at 255, then generates the values as per the pattern described above. The pattern generator just loops through the seven colour patterns.
using System;
class Program {
static void Main(string[] args) {
ColourGenerator generator = new ColourGenerator();
for (int i = 0; i < 896; i++) {
Console.WriteLine(string.Format("{0}: {1}", i, generator.NextColour()));
}
}
}
public class ColourGenerator {
private int index = 0;
private IntensityGenerator intensityGenerator = new IntensityGenerator();
public string NextColour() {
string colour = string.Format(PatternGenerator.NextPattern(index),
intensityGenerator.NextIntensity(index));
index++;
return colour;
}
}
public class PatternGenerator {
public static string NextPattern(int index) {
switch (index % 7) {
case 0: return "{0}0000";
case 1: return "00{0}00";
case 2: return "0000{0}";
case 3: return "{0}{0}00";
case 4: return "{0}00{0}";
case 5: return "00{0}{0}";
case 6: return "{0}{0}{0}";
default: throw new Exception("Math error");
}
}
}
public class IntensityGenerator {
private IntensityValueWalker walker;
private int current;
public string NextIntensity(int index) {
if (index == 0) {
current = 255;
}
else if (index % 7 == 0) {
if (walker == null) {
walker = new IntensityValueWalker();
}
else {
walker.MoveNext();
}
current = walker.Current.Value;
}
string currentText = current.ToString("X");
if (currentText.Length == 1) currentText = "0" + currentText;
return currentText;
}
}
public class IntensityValue {
private IntensityValue mChildA;
private IntensityValue mChildB;
public IntensityValue(IntensityValue parent, int value, int level) {
if (level > 7) throw new Exception("There are no more colours left");
Value = value;
Parent = parent;
Level = level;
}
public int Level { get; set; }
public int Value { get; set; }
public IntensityValue Parent { get; set; }
public IntensityValue ChildA {
get {
return mChildA ?? (mChildA = new IntensityValue(this, this.Value - (1<<(7-Level)), Level+1));
}
}
public IntensityValue ChildB {
get {
return mChildB ?? (mChildB = new IntensityValue(this, Value + (1<<(7-Level)), Level+1));
}
}
}
public class IntensityValueWalker {
public IntensityValueWalker() {
Current = new IntensityValue(null, 1<<7, 1);
}
public IntensityValue Current { get; set; }
public void MoveNext() {
if (Current.Parent == null) {
Current = Current.ChildA;
}
else if (Current.Parent.ChildA == Current) {
Current = Current.Parent.ChildB;
}
else {
int levelsUp = 1;
Current = Current.Parent;
while (Current.Parent != null && Current == Current.Parent.ChildB) {
Current = Current.Parent;
levelsUp++;
}
if (Current.Parent != null) {
Current = Current.Parent.ChildB;
}
else {
levelsUp++;
}
for (int i = 0; i < levelsUp; i++) {
Current = Current.ChildA;
}
}
}
}
To implement a variation list where by your colors go, 255 then use all possibilities of that up, then add 0 and all RGB patterns with those two values. Then add 128 and all RGB combinations with those. Then 64. Then 192. Etc.
In Java,
public Color getColor(int i) {
return new Color(getRGB(i));
}
public int getRGB(int index) {
int[] p = getPattern(index);
return getElement(p[0]) << 16 | getElement(p[1]) << 8 | getElement(p[2]);
}
public int getElement(int index) {
int value = index - 1;
int v = 0;
for (int i = 0; i < 8; i++) {
v = v | (value & 1);
v <<= 1;
value >>= 1;
}
v >>= 1;
return v & 0xFF;
}
public int[] getPattern(int index) {
int n = (int)Math.cbrt(index);
index -= (n*n*n);
int[] p = new int[3];
Arrays.fill(p,n);
if (index == 0) {
return p;
}
index--;
int v = index % 3;
index = index / 3;
if (index < n) {
p[v] = index % n;
return p;
}
index -= n;
p[v ] = index / n;
p[++v % 3] = index % n;
return p;
}
This will produce patterns of that type infinitely (2^24) into the future. However, after a hundred or so spots you likely won't see much of a difference between a color with 0 or 32 in the blue's place.
You might be better off normalizing this into a different color space. LAB color space for example with the L,A,B values normalized and converted. So the distinctness of the color is pushed through something more akin to the human eye.
getElement() reverses the endian of an 8 bit number, and starts counting from -1 rather than 0 (masking with 255). So it goes 255,0,127,192,64,... as the number grows it moves less and less significant bits, subdividing the number.
getPattern() determines what the most significant element in the pattern should be (it's the cube root). Then proceeds to break down the 3N²+3N+1 different patterns that involve that most significant element.
This algorithm will produce (first 128 values):
#FFFFFF
#000000
#FF0000
#00FF00
#0000FF
#FFFF00
#00FFFF
#FF00FF
#808080
#FF8080
#80FF80
#8080FF
#008080
#800080
#808000
#FFFF80
#80FFFF
#FF80FF
#FF0080
#80FF00
#0080FF
#00FF80
#8000FF
#FF8000
#000080
#800000
#008000
#404040
#FF4040
#40FF40
#4040FF
#004040
#400040
#404000
#804040
#408040
#404080
#FFFF40
#40FFFF
#FF40FF
#FF0040
#40FF00
#0040FF
#FF8040
#40FF80
#8040FF
#00FF40
#4000FF
#FF4000
#000040
#400000
#004000
#008040
#400080
#804000
#80FF40
#4080FF
#FF4080
#800040
#408000
#004080
#808040
#408080
#804080
#C0C0C0
#FFC0C0
#C0FFC0
#C0C0FF
#00C0C0
#C000C0
#C0C000
#80C0C0
#C080C0
#C0C080
#40C0C0
#C040C0
#C0C040
#FFFFC0
#C0FFFF
#FFC0FF
#FF00C0
#C0FF00
#00C0FF
#FF80C0
#C0FF80
#80C0FF
#FF40C0
#C0FF40
#40C0FF
#00FFC0
#C000FF
#FFC000
#0000C0
#C00000
#00C000
#0080C0
#C00080
#80C000
#0040C0
#C00040
#40C000
#80FFC0
#C080FF
#FFC080
#8000C0
#C08000
#00C080
#8080C0
#C08080
#80C080
#8040C0
#C08040
#40C080
#40FFC0
#C040FF
#FFC040
#4000C0
#C04000
#00C040
#4080C0
#C04080
#80C040
#4040C0
#C04040
#40C040
#202020
#FF2020
#20FF20
Read left to right, top to bottom. 729 colors (9³). So all the patterns up to n = 9. You'll notice the speed at which they start to clash. There's only so many WRGBCYMK variations. And this solution, while clever basically only does different shades of primary colors.
Much of the clashing is due to green and how similar most greens look to most people. The demand that each be maximally different at start rather than just different enough to not be the same color. And basic flaws in the idea resulting in primary colors patterns, and identical hues.
Using CIELab2000 Color Space and Distance Routine to randomly select and try 10k different colors and find the maximally-distant minimum-distance from previous colors, (pretty much the definition of the request) avoids clashing longer than the above solution:
Which could be just called a static list for the Easy Way. It took an hour and a half to generate 729 entries:
#9BC4E5
#310106
#04640D
#FEFB0A
#FB5514
#E115C0
#00587F
#0BC582
#FEB8C8
#9E8317
#01190F
#847D81
#58018B
#B70639
#703B01
#F7F1DF
#118B8A
#4AFEFA
#FCB164
#796EE6
#000D2C
#53495F
#F95475
#61FC03
#5D9608
#DE98FD
#98A088
#4F584E
#248AD0
#5C5300
#9F6551
#BCFEC6
#932C70
#2B1B04
#B5AFC4
#D4C67A
#AE7AA1
#C2A393
#0232FD
#6A3A35
#BA6801
#168E5C
#16C0D0
#C62100
#014347
#233809
#42083B
#82785D
#023087
#B7DAD2
#196956
#8C41BB
#ECEDFE
#2B2D32
#94C661
#F8907D
#895E6B
#788E95
#FB6AB8
#576094
#DB1474
#8489AE
#860E04
#FBC206
#6EAB9B
#F2CDFE
#645341
#760035
#647A41
#496E76
#E3F894
#F9D7CD
#876128
#A1A711
#01FB92
#FD0F31
#BE8485
#C660FB
#120104
#D48958
#05AEE8
#C3C1BE
#9F98F8
#1167D9
#D19012
#B7D802
#826392
#5E7A6A
#B29869
#1D0051
#8BE7FC
#76E0C1
#BACFA7
#11BA09
#462C36
#65407D
#491803
#F5D2A8
#03422C
#72A46E
#128EAC
#47545E
#B95C69
#A14D12
#C4C8FA
#372A55
#3F3610
#D3A2C6
#719FFA
#0D841A
#4C5B32
#9DB3B7
#B14F8F
#747103
#9F816D
#D26A5B
#8B934B
#F98500
#002935
#D7F3FE
#FCB899
#1C0720
#6B5F61
#F98A9D
#9B72C2
#A6919D
#2C3729
#D7C70B
#9F9992
#EFFBD0
#FDE2F1
#923A52
#5140A7
#BC14FD
#6D706C
#0007C4
#C6A62F
#000C14
#904431
#600013
#1C1B08
#693955
#5E7C99
#6C6E82
#D0AFB3
#493B36
#AC93CE
#C4BA9C
#09C4B8
#69A5B8
#374869
#F868ED
#E70850
#C04841
#C36333
#700366
#8A7A93
#52351D
#B503A2
#D17190
#A0F086
#7B41FC
#0EA64F
#017499
#08A882
#7300CD
#A9B074
#4E6301
#AB7E41
#547FF4
#134DAC
#FDEC87
#056164
#FE12A0
#C264BA
#939DAD
#0BCDFA
#277442
#1BDE4A
#826958
#977678
#BAFCE8
#7D8475
#8CCF95
#726638
#FEA8EB
#EAFEF0
#6B9279
#C2FE4B
#304041
#1EA6A7
#022403
#062A47
#054B17
#F4C673
#02FEC7
#9DBAA8
#775551
#835536
#565BCC
#80D7D2
#7AD607
#696F54
#87089A
#664B19
#242235
#7DB00D
#BFC7D6
#D5A97E
#433F31
#311A18
#FDB2AB
#D586C9
#7A5FB1
#32544A
#EFE3AF
#859D96
#2B8570
#8B282D
#E16A07
#4B0125
#021083
#114558
#F707F9
#C78571
#7FB9BC
#FC7F4B
#8D4A92
#6B3119
#884F74
#994E4F
#9DA9D3
#867B40
#CED5C4
#1CA2FE
#D9C5B4
#FEAA00
#507B01
#A7D0DB
#53858D
#588F4A
#FBEEEC
#FC93C1
#D7CCD4
#3E4A02
#C8B1E2
#7A8B62
#9A5AE2
#896C04
#B1121C
#402D7D
#858701
#D498A6
#B484EF
#5C474C
#067881
#C0F9FC
#726075
#8D3101
#6C93B2
#A26B3F
#AA6582
#4F4C4F
#5A563D
#E83005
#32492D
#FC7272
#B9C457
#552A5B
#B50464
#616E79
#DCE2E4
#CF8028
#0AE2F0
#4F1E24
#FD5E46
#4B694E
#C5DEFC
#5DC262
#022D26
#7776B8
#FD9F66
#B049B8
#988F73
#BE385A
#2B2126
#54805A
#141B55
#67C09B
#456989
#DDC1D9
#166175
#C1E29C
#A397B5
#2E2922
#ABDBBE
#B4A6A8
#A06B07
#A99949
#0A0618
#B14E2E
#60557D
#D4A556
#82A752
#4A005B
#3C404F
#6E6657
#7E8BD5
#1275B8
#D79E92
#230735
#661849
#7A8391
#FE0F7B
#B0B6A9
#629591
#D05591
#97B68A
#97939A
#035E38
#53E19E
#DFD7F9
#02436C
#525A72
#059A0E
#3E736C
#AC8E87
#D10C92
#B9906E
#66BDFD
#C0ABFD
#0734BC
#341224
#8AAAC1
#0E0B03
#414522
#6A2F3E
#2D9A8A
#4568FD
#FDE6D2
#FEE007
#9A003C
#AC8190
#DCDD58
#B7903D
#1F2927
#9B02E6
#827A71
#878B8A
#8F724F
#AC4B70
#37233B
#385559
#F347C7
#9DB4FE
#D57179
#DE505A
#37F7DD
#503500
#1C2401
#DD0323
#00A4BA
#955602
#FA5B94
#AA766C
#B8E067
#6A807E
#4D2E27
#73BED7
#D7BC8A
#614539
#526861
#716D96
#829A17
#210109
#436C2D
#784955
#987BAB
#8F0152
#0452FA
#B67757
#A1659F
#D4F8D8
#48416F
#DEBAAF
#A5A9AA
#8C6B83
#403740
#70872B
#D9744D
#151E2C
#5C5E5E
#B47C02
#F4CBD0
#E49D7D
#DD9954
#B0A18B
#2B5308
#EDFD64
#9D72FC
#2A3351
#68496C
#C94801
#EED05E
#826F6D
#E0D6BB
#5B6DB4
#662F98
#0C97CA
#C1CA89
#755A03
#DFA619
#CD70A8
#BBC9C7
#F6BCE3
#A16462
#01D0AA
#87C6B3
#E7B2FA
#D85379
#643AD5
#D18AAE
#13FD5E
#B3E3FD
#C977DB
#C1A7BB
#9286CB
#A19B6A
#8FFED7
#6B1F17
#DF503A
#10DDD7
#9A8457
#60672F
#7D327D
#DD8782
#59AC42
#82FDB8
#FC8AE7
#909F6F
#B691AE
#B811CD
#BCB24E
#CB4BD9
#2B2304
#AA9501
#5D5096
#403221
#F9FAB4
#3990FC
#70DE7F
#95857F
#84A385
#50996F
#797B53
#7B6142
#81D5FE
#9CC428
#0B0438
#3E2005
#4B7C91
#523854
#005EA9
#F0C7AD
#ACB799
#FAC08E
#502239
#BFAB6A
#2B3C48
#0EB5D8
#8A5647
#49AF74
#067AE9
#F19509
#554628
#4426A4
#7352C9
#3F4287
#8B655E
#B480BF
#9BA74C
#5F514C
#CC9BDC
#BA7942
#1C4138
#3C3C3A
#29B09C
#02923F
#701D2B
#36577C
#3F00EA
#3D959E
#440601
#8AEFF3
#6D442A
#BEB1A8
#A11C02
#8383FE
#A73839
#DBDE8A
#0283B3
#888597
#32592E
#F5FDFA
#01191B
#AC707A
#B6BD03
#027B59
#7B4F08
#957737
#83727D
#035543
#6F7E64
#C39999
#52847A
#925AAC
#77CEDA
#516369
#E0D7D0
#FCDD97
#555424
#96E6B6
#85BB74
#5E2074
#BD5E48
#9BEE53
#1A351E
#3148CD
#71575F
#69A6D0
#391A62
#E79EA0
#1C0F03
#1B1636
#D20C39
#765396
#7402FE
#447F3E
#CFD0A8
#3A2600
#685AFC
#A4B3C6
#534302
#9AA097
#FD5154
#9B0085
#403956
#80A1A7
#6E7A9A
#605E6A
#86F0E2
#5A2B01
#7E3D43
#ED823B
#32331B
#424837
#40755E
#524F48
#B75807
#B40080
#5B8CA1
#FDCFE5
#CCFEAC
#755847
#CAB296
#C0D6E3
#2D7100
#D5E4DE
#362823
#69C63C
#AC3801
#163132
#4750A6
#61B8B2
#FCC4B5
#DEBA2E
#FE0449
#737930
#8470AB
#687D87
#D7B760
#6AAB86
#8398B8
#B7B6BF
#92C4A1
#B6084F
#853B5E
#D0BCBA
#92826D
#C6DDC6
#BE5F5A
#280021
#435743
#874514
#63675A
#E97963
#8F9C9E
#985262
#909081
#023508
#DDADBF
#D78493
#363900
#5B0120
#603C47
#C3955D
#AC61CB
#FD7BA7
#716C74
#8D895B
#071001
#82B4F2
#B6BBD8
#71887A
#8B9FE3
#997158
#65A6AB
#2E3067
#321301
#FEECCB
#3B5E72
#C8FE85
#A1DCDF
#CB49A6
#B1C5E4
#3E5EB0
#88AEA7
#04504C
#975232
#6786B9
#068797
#9A98C4
#A1C3C2
#1C3967
#DBEA07
#789658
#E7E7C6
#A6C886
#957F89
#752E62
#171518
#A75648
#01D26F
#0F535D
#047E76
#C54754
#5D6E88
#AB9483
#803B99
#FA9C48
#4A8A22
#654A5C
#965F86
#9D0CBB
#A0E8A0
#D3DBFA
#FD908F
#AEAB85
#A13B89
#F1B350
#066898
#948A42
#C8BEDE
#19252C
#7046AA
#E1EEFC
#3E6557
#CD3F26
#2B1925
#DDAD94
#C0B109
#37DFFE
#039676
#907468
#9E86A5
#3A1B49
#BEE5B7
#C29501
#9E3645
#DC580A
#645631
#444B4B
#FD1A63
#DDE5AE
#887800
#36006F
#3A6260
#784637
#FEA0B7
#A3E0D2
#6D6316
#5F7172
#B99EC7
#777A7E
#E0FEFD
#E16DC5
#01344B
#F8F8FC
#9F9FB5
#182617
#FE3D21
#7D0017
#822F21
#EFD9DC
#6E68C4
#35473E
#007523
#767667
#A6825D
#83DC5F
#227285
#A95E34
#526172
#979730
#756F6D
#716259
#E8B2B5
#B6C9BB
#9078DA
#4F326E
#B2387B
#888C6F
#314B5F
#E5B678
#38A3C6
#586148
#5C515B
#CDCCE1
#C8977F
Using brute force to (testing all 16,777,216 RGB colors through CIELab Delta2000 / Starting with black) produces a series. Which starts to clash at around 26 but could make it to 30 or 40 with visual inspection and manual dropping (which can't be done with a computer). So doing the absolute maximum one can programmatically only makes a couple dozen distinct colors. A discrete list is your best bet. You will get more discrete colors with a list than you would programmatically. The easy way is the best solution, start mixing and matching with other ways to alter your data than color.
#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
Update: I continued this for about a month so, at 1024 brute force.
public static final String[] indexcolors = new String[]{
"#000000", "#FFFF00", "#1CE6FF", "#FF34FF", "#FF4A46", "#008941", "#006FA6", "#A30059",
"#FFDBE5", "#7A4900", "#0000A6", "#63FFAC", "#B79762", "#004D43", "#8FB0FF", "#997D87",
"#5A0007", "#809693", "#FEFFE6", "#1B4400", "#4FC601", "#3B5DFF", "#4A3B53", "#FF2F80",
"#61615A", "#BA0900", "#6B7900", "#00C2A0", "#FFAA92", "#FF90C9", "#B903AA", "#D16100",
"#DDEFFF", "#000035", "#7B4F4B", "#A1C299", "#300018", "#0AA6D8", "#013349", "#00846F",
"#372101", "#FFB500", "#C2FFED", "#A079BF", "#CC0744", "#C0B9B2", "#C2FF99", "#001E09",
"#00489C", "#6F0062", "#0CBD66", "#EEC3FF", "#456D75", "#B77B68", "#7A87A1", "#788D66",
"#885578", "#FAD09F", "#FF8A9A", "#D157A0", "#BEC459", "#456648", "#0086ED", "#886F4C",
"#34362D", "#B4A8BD", "#00A6AA", "#452C2C", "#636375", "#A3C8C9", "#FF913F", "#938A81",
"#575329", "#00FECF", "#B05B6F", "#8CD0FF", "#3B9700", "#04F757", "#C8A1A1", "#1E6E00",
"#7900D7", "#A77500", "#6367A9", "#A05837", "#6B002C", "#772600", "#D790FF", "#9B9700",
"#549E79", "#FFF69F", "#201625", "#72418F", "#BC23FF", "#99ADC0", "#3A2465", "#922329",
"#5B4534", "#FDE8DC", "#404E55", "#0089A3", "#CB7E98", "#A4E804", "#324E72", "#6A3A4C",
"#83AB58", "#001C1E", "#D1F7CE", "#004B28", "#C8D0F6", "#A3A489", "#806C66", "#222800",
"#BF5650", "#E83000", "#66796D", "#DA007C", "#FF1A59", "#8ADBB4", "#1E0200", "#5B4E51",
"#C895C5", "#320033", "#FF6832", "#66E1D3", "#CFCDAC", "#D0AC94", "#7ED379", "#012C58",
"#7A7BFF", "#D68E01", "#353339", "#78AFA1", "#FEB2C6", "#75797C", "#837393", "#943A4D",
"#B5F4FF", "#D2DCD5", "#9556BD", "#6A714A", "#001325", "#02525F", "#0AA3F7", "#E98176",
"#DBD5DD", "#5EBCD1", "#3D4F44", "#7E6405", "#02684E", "#962B75", "#8D8546", "#9695C5",
"#E773CE", "#D86A78", "#3E89BE", "#CA834E", "#518A87", "#5B113C", "#55813B", "#E704C4",
"#00005F", "#A97399", "#4B8160", "#59738A", "#FF5DA7", "#F7C9BF", "#643127", "#513A01",
"#6B94AA", "#51A058", "#A45B02", "#1D1702", "#E20027", "#E7AB63", "#4C6001", "#9C6966",
"#64547B", "#97979E", "#006A66", "#391406", "#F4D749", "#0045D2", "#006C31", "#DDB6D0",
"#7C6571", "#9FB2A4", "#00D891", "#15A08A", "#BC65E9", "#FFFFFE", "#C6DC99", "#203B3C",
"#671190", "#6B3A64", "#F5E1FF", "#FFA0F2", "#CCAA35", "#374527", "#8BB400", "#797868",
"#C6005A", "#3B000A", "#C86240", "#29607C", "#402334", "#7D5A44", "#CCB87C", "#B88183",
"#AA5199", "#B5D6C3", "#A38469", "#9F94F0", "#A74571", "#B894A6", "#71BB8C", "#00B433",
"#789EC9", "#6D80BA", "#953F00", "#5EFF03", "#E4FFFC", "#1BE177", "#BCB1E5", "#76912F",
"#003109", "#0060CD", "#D20096", "#895563", "#29201D", "#5B3213", "#A76F42", "#89412E",
"#1A3A2A", "#494B5A", "#A88C85", "#F4ABAA", "#A3F3AB", "#00C6C8", "#EA8B66", "#958A9F",
"#BDC9D2", "#9FA064", "#BE4700", "#658188", "#83A485", "#453C23", "#47675D", "#3A3F00",
"#061203", "#DFFB71", "#868E7E", "#98D058", "#6C8F7D", "#D7BFC2", "#3C3E6E", "#D83D66",
"#2F5D9B", "#6C5E46", "#D25B88", "#5B656C", "#00B57F", "#545C46", "#866097", "#365D25",
"#252F99", "#00CCFF", "#674E60", "#FC009C", "#92896B", "#1E2324", "#DEC9B2", "#9D4948",
"#85ABB4", "#342142", "#D09685", "#A4ACAC", "#00FFFF", "#AE9C86", "#742A33", "#0E72C5",
"#AFD8EC", "#C064B9", "#91028C", "#FEEDBF", "#FFB789", "#9CB8E4", "#AFFFD1", "#2A364C",
"#4F4A43", "#647095", "#34BBFF", "#807781", "#920003", "#B3A5A7", "#018615", "#F1FFC8",
"#976F5C", "#FF3BC1", "#FF5F6B", "#077D84", "#F56D93", "#5771DA", "#4E1E2A", "#830055",
"#02D346", "#BE452D", "#00905E", "#BE0028", "#6E96E3", "#007699", "#FEC96D", "#9C6A7D",
"#3FA1B8", "#893DE3", "#79B4D6", "#7FD4D9", "#6751BB", "#B28D2D", "#E27A05", "#DD9CB8",
"#AABC7A", "#980034", "#561A02", "#8F7F00", "#635000", "#CD7DAE", "#8A5E2D", "#FFB3E1",
"#6B6466", "#C6D300", "#0100E2", "#88EC69", "#8FCCBE", "#21001C", "#511F4D", "#E3F6E3",
"#FF8EB1", "#6B4F29", "#A37F46", "#6A5950", "#1F2A1A", "#04784D", "#101835", "#E6E0D0",
"#FF74FE", "#00A45F", "#8F5DF8", "#4B0059", "#412F23", "#D8939E", "#DB9D72", "#604143",
"#B5BACE", "#989EB7", "#D2C4DB", "#A587AF", "#77D796", "#7F8C94", "#FF9B03", "#555196",
"#31DDAE", "#74B671", "#802647", "#2A373F", "#014A68", "#696628", "#4C7B6D", "#002C27",
"#7A4522", "#3B5859", "#E5D381", "#FFF3FF", "#679FA0", "#261300", "#2C5742", "#9131AF",
"#AF5D88", "#C7706A", "#61AB1F", "#8CF2D4", "#C5D9B8", "#9FFFFB", "#BF45CC", "#493941",
"#863B60", "#B90076", "#003177", "#C582D2", "#C1B394", "#602B70", "#887868", "#BABFB0",
"#030012", "#D1ACFE", "#7FDEFE", "#4B5C71", "#A3A097", "#E66D53", "#637B5D", "#92BEA5",
"#00F8B3", "#BEDDFF", "#3DB5A7", "#DD3248", "#B6E4DE", "#427745", "#598C5A", "#B94C59",
"#8181D5", "#94888B", "#FED6BD", "#536D31", "#6EFF92", "#E4E8FF", "#20E200", "#FFD0F2",
"#4C83A1", "#BD7322", "#915C4E", "#8C4787", "#025117", "#A2AA45", "#2D1B21", "#A9DDB0",
"#FF4F78", "#528500", "#009A2E", "#17FCE4", "#71555A", "#525D82", "#00195A", "#967874",
"#555558", "#0B212C", "#1E202B", "#EFBFC4", "#6F9755", "#6F7586", "#501D1D", "#372D00",
"#741D16", "#5EB393", "#B5B400", "#DD4A38", "#363DFF", "#AD6552", "#6635AF", "#836BBA",
"#98AA7F", "#464836", "#322C3E", "#7CB9BA", "#5B6965", "#707D3D", "#7A001D", "#6E4636",
"#443A38", "#AE81FF", "#489079", "#897334", "#009087", "#DA713C", "#361618", "#FF6F01",
"#006679", "#370E77", "#4B3A83", "#C9E2E6", "#C44170", "#FF4526", "#73BE54", "#C4DF72",
"#ADFF60", "#00447D", "#DCCEC9", "#BD9479", "#656E5B", "#EC5200", "#FF6EC2", "#7A617E",
"#DDAEA2", "#77837F", "#A53327", "#608EFF", "#B599D7", "#A50149", "#4E0025", "#C9B1A9",
"#03919A", "#1B2A25", "#E500F1", "#982E0B", "#B67180", "#E05859", "#006039", "#578F9B",
"#305230", "#CE934C", "#B3C2BE", "#C0BAC0", "#B506D3", "#170C10", "#4C534F", "#224451",
"#3E4141", "#78726D", "#B6602B", "#200441", "#DDB588", "#497200", "#C5AAB6", "#033C61",
"#71B2F5", "#A9E088", "#4979B0", "#A2C3DF", "#784149", "#2D2B17", "#3E0E2F", "#57344C",
"#0091BE", "#E451D1", "#4B4B6A", "#5C011A", "#7C8060", "#FF9491", "#4C325D", "#005C8B",
"#E5FDA4", "#68D1B6", "#032641", "#140023", "#8683A9", "#CFFF00", "#A72C3E", "#34475A",
"#B1BB9A", "#B4A04F", "#8D918E", "#A168A6", "#813D3A", "#425218", "#DA8386", "#776133",
"#563930", "#8498AE", "#90C1D3", "#B5666B", "#9B585E", "#856465", "#AD7C90", "#E2BC00",
"#E3AAE0", "#B2C2FE", "#FD0039", "#009B75", "#FFF46D", "#E87EAC", "#DFE3E6", "#848590",
"#AA9297", "#83A193", "#577977", "#3E7158", "#C64289", "#EA0072", "#C4A8CB", "#55C899",
"#E78FCF", "#004547", "#F6E2E3", "#966716", "#378FDB", "#435E6A", "#DA0004", "#1B000F",
"#5B9C8F", "#6E2B52", "#011115", "#E3E8C4", "#AE3B85", "#EA1CA9", "#FF9E6B", "#457D8B",
"#92678B", "#00CDBB", "#9CCC04", "#002E38", "#96C57F", "#CFF6B4", "#492818", "#766E52",
"#20370E", "#E3D19F", "#2E3C30", "#B2EACE", "#F3BDA4", "#A24E3D", "#976FD9", "#8C9FA8",
"#7C2B73", "#4E5F37", "#5D5462", "#90956F", "#6AA776", "#DBCBF6", "#DA71FF", "#987C95",
"#52323C", "#BB3C42", "#584D39", "#4FC15F", "#A2B9C1", "#79DB21", "#1D5958", "#BD744E",
"#160B00", "#20221A", "#6B8295", "#00E0E4", "#102401", "#1B782A", "#DAA9B5", "#B0415D",
"#859253", "#97A094", "#06E3C4", "#47688C", "#7C6755", "#075C00", "#7560D5", "#7D9F00",
"#C36D96", "#4D913E", "#5F4276", "#FCE4C8", "#303052", "#4F381B", "#E5A532", "#706690",
"#AA9A92", "#237363", "#73013E", "#FF9079", "#A79A74", "#029BDB", "#FF0169", "#C7D2E7",
"#CA8869", "#80FFCD", "#BB1F69", "#90B0AB", "#7D74A9", "#FCC7DB", "#99375B", "#00AB4D",
"#ABAED1", "#BE9D91", "#E6E5A7", "#332C22", "#DD587B", "#F5FFF7", "#5D3033", "#6D3800",
"#FF0020", "#B57BB3", "#D7FFE6", "#C535A9", "#260009", "#6A8781", "#A8ABB4", "#D45262",
"#794B61", "#4621B2", "#8DA4DB", "#C7C890", "#6FE9AD", "#A243A7", "#B2B081", "#181B00",
"#286154", "#4CA43B", "#6A9573", "#A8441D", "#5C727B", "#738671", "#D0CFCB", "#897B77",
"#1F3F22", "#4145A7", "#DA9894", "#A1757A", "#63243C", "#ADAAFF", "#00CDE2", "#DDBC62",
"#698EB1", "#208462", "#00B7E0", "#614A44", "#9BBB57", "#7A5C54", "#857A50", "#766B7E",
"#014833", "#FF8347", "#7A8EBA", "#274740", "#946444", "#EBD8E6", "#646241", "#373917",
"#6AD450", "#81817B", "#D499E3", "#979440", "#011A12", "#526554", "#B5885C", "#A499A5",
"#03AD89", "#B3008B", "#E3C4B5", "#96531F", "#867175", "#74569E", "#617D9F", "#E70452",
"#067EAF", "#A697B6", "#B787A8", "#9CFF93", "#311D19", "#3A9459", "#6E746E", "#B0C5AE",
"#84EDF7", "#ED3488", "#754C78", "#384644", "#C7847B", "#00B6C5", "#7FA670", "#C1AF9E",
"#2A7FFF", "#72A58C", "#FFC07F", "#9DEBDD", "#D97C8E", "#7E7C93", "#62E674", "#B5639E",
"#FFA861", "#C2A580", "#8D9C83", "#B70546", "#372B2E", "#0098FF", "#985975", "#20204C",
"#FF6C60", "#445083", "#8502AA", "#72361F", "#9676A3", "#484449", "#CED6C2", "#3B164A",
"#CCA763", "#2C7F77", "#02227B", "#A37E6F", "#CDE6DC", "#CDFFFB", "#BE811A", "#F77183",
"#EDE6E2", "#CDC6B4", "#FFE09E", "#3A7271", "#FF7B59", "#4E4E01", "#4AC684", "#8BC891",
"#BC8A96", "#CF6353", "#DCDE5C", "#5EAADD", "#F6A0AD", "#E269AA", "#A3DAE4", "#436E83",
"#002E17", "#ECFBFF", "#A1C2B6", "#50003F", "#71695B", "#67C4BB", "#536EFF", "#5D5A48",
"#890039", "#969381", "#371521", "#5E4665", "#AA62C3", "#8D6F81", "#2C6135", "#410601",
"#564620", "#E69034", "#6DA6BD", "#E58E56", "#E3A68B", "#48B176", "#D27D67", "#B5B268",
"#7F8427", "#FF84E6", "#435740", "#EAE408", "#F4F5FF", "#325800", "#4B6BA5", "#ADCEFF",
"#9B8ACC", "#885138", "#5875C1", "#7E7311", "#FEA5CA", "#9F8B5B", "#A55B54", "#89006A",
"#AF756F", "#2A2000", "#576E4A", "#7F9EFF", "#7499A1", "#FFB550", "#00011E", "#D1511C",
"#688151", "#BC908A", "#78C8EB", "#8502FF", "#483D30", "#C42221", "#5EA7FF", "#785715",
"#0CEA91", "#FFFAED", "#B3AF9D", "#3E3D52", "#5A9BC2", "#9C2F90", "#8D5700", "#ADD79C",
"#00768B", "#337D00", "#C59700", "#3156DC", "#944575", "#ECFFDC", "#D24CB2", "#97703C",
"#4C257F", "#9E0366", "#88FFEC", "#B56481", "#396D2B", "#56735F", "#988376", "#9BB195",
"#A9795C", "#E4C5D3", "#9F4F67", "#1E2B39", "#664327", "#AFCE78", "#322EDF", "#86B487",
"#C23000", "#ABE86B", "#96656D", "#250E35", "#A60019", "#0080CF", "#CAEFFF", "#323F61",
"#A449DC", "#6A9D3B", "#FF5AE4", "#636A01", "#D16CDA", "#736060", "#FFBAAD", "#D369B4",
"#FFDED6", "#6C6D74", "#927D5E", "#845D70", "#5B62C1", "#2F4A36", "#E45F35", "#FF3B53",
"#AC84DD", "#762988", "#70EC98", "#408543", "#2C3533", "#2E182D", "#323925", "#19181B",
"#2F2E2C", "#023C32", "#9B9EE2", "#58AFAD", "#5C424D", "#7AC5A6", "#685D75", "#B9BCBD",
"#834357", "#1A7B42", "#2E57AA", "#E55199", "#316E47", "#CD00C5", "#6A004D", "#7FBBEC",
"#F35691", "#D7C54A", "#62ACB7", "#CBA1BC", "#A28A9A", "#6C3F3B", "#FFE47D", "#DCBAE3",
"#5F816D", "#3A404A", "#7DBF32", "#E6ECDC", "#852C19", "#285366", "#B8CB9C", "#0E0D00",
"#4B5D56", "#6B543F", "#E27172", "#0568EC", "#2EB500", "#D21656", "#EFAFFF", "#682021",
"#2D2011", "#DA4CFF", "#70968E", "#FF7B7D", "#4A1930", "#E8C282", "#E7DBBC", "#A68486",
"#1F263C", "#36574E", "#52CE79", "#ADAAA9", "#8A9F45", "#6542D2", "#00FB8C", "#5D697B",
"#CCD27F", "#94A5A1", "#790229", "#E383E6", "#7EA4C1", "#4E4452", "#4B2C00", "#620B70",
"#314C1E", "#874AA6", "#E30091", "#66460A", "#EB9A8B", "#EAC3A3", "#98EAB3", "#AB9180",
"#B8552F", "#1A2B2F", "#94DDC5", "#9D8C76", "#9C8333", "#94A9C9", "#392935", "#8C675E",
"#CCE93A", "#917100", "#01400B", "#449896", "#1CA370", "#E08DA7", "#8B4A4E", "#667776",
"#4692AD", "#67BDA8", "#69255C", "#D3BFFF", "#4A5132", "#7E9285", "#77733C", "#E7A0CC",
"#51A288", "#2C656A", "#4D5C5E", "#C9403A", "#DDD7F3", "#005844", "#B4A200", "#488F69",
"#858182", "#D4E9B9", "#3D7397", "#CAE8CE", "#D60034", "#AA6746", "#9E5585", "#BA6200"
};
I have put up a page online for procedurally generating visually distinct colors:
http://phrogz.net/css/distinct-colors.html
Unlike other answers here that evenly step across RGB or HSV space (where there is a nonlinear relationship between the axis values and the perceptual differences), my page uses the standard CMI(I:c) color distance algorithm to prevent two colors from being too visually close.
The final tab of the page allows you to sort the values in several ways, and then interleave them (ordered shuffle) so that you get very distinct colors placed next to one another.
As of this writing, it only works well in Chrome and Safari, with a shim for Firefox; it uses HTML5 range input sliders in the interface, which IE9 and Firefox do not yet support natively.