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 pro
There's a flaw in the previous RGB solutions. They don't take advantage of the whole color space since they use a color value and 0 for the channels:
#006600
#330000
#FF00FF
Instead they should be using all the possible color values to generate mixed colors that can have up to 3 different values across the color channels:
#336600
#FF0066
#33FF66
Using the full color space you can generate more distinct colors. For example, if you have 4 values per channel, then 4*4*4=64 colors can be generated. With the other scheme, only 4*7+1=29 colors can be generated.
If you want N colors, then the number of values per channel required is: ceil(cube_root(N))
With that, you can then determine the possible (0-255 range) values (python):
max = 255
segs = int(num**(Decimal("1.0")/3))
step = int(max/segs)
p = [(i*step) for i in xrange(segs)]
values = [max]
values.extend(p)
Then you can iterate over the RGB colors (this is not recommended):
total = 0
for red in values:
for green in values:
for blue in values:
if total <= N:
print color(red, green, blue)
total += 1
Nested loops will work, but are not recommended since it will favor the blue channel and the resulting colors will not have enough red (N will most likely be less than the number of all possible color values).
You can create a better algorithm for the loops where each channel is treated equally and more distinct color values are favored over small ones.
I have a solution, but didn't want to post it since it isn't the easiest to understand or efficient. But, you can view the solution if you really want to.
Here is a sample of 64 generated colors: 64 colors
I would start with a set brightness 100% and go around primary colors first:
FF0000, 00FF00, 0000FF
then the combinations
FFFF00, FF00FF, 00FFFF
next for example halve the brightness and do same round. There's not too many really clearly distinct colors, after these I would start to vary the line width and do dotted/dashed lines etc.
for getting nth colour. Just this kind of code would be enough. This i have use in my opencv clustering problem. This will create different colours as col changes.
for(int col=1;col<CLUSTER_COUNT+1;col++){
switch(col%6)
{
case 1:cout<<Scalar(0,0,(int)(255/(int)(col/6+1)))<<endl;break;
case 2:cout<<Scalar(0,(int)(255/(int)(col/6+1)),0)<<endl;break;
case 3:cout<<Scalar((int)(255/(int)(col/6+1)),0,0)<<endl;break;
case 4:cout<<Scalar(0,(int)(255/(int)(col/6+1)),(int)(255/(int)(col/6+1)))<<endl;break;
case 5:cout<<Scalar((int)(255/(int)(col/6+1)),0,(int)(255/(int)(col/6+1)))<<endl;break;
case 0:cout<<Scalar((int)(255/(int)(col/6)),(int)(255/(int)(col/6)),0)<<endl;break;
}
}
In case someone needs to generate random medium to high dark color for white foreground in C#, here is the code.
[DllImport("shlwapi.dll")]
public static extern int ColorHLSToRGB(int H, int L, int S);
public static string GetRandomDarkColor()
{
int h = 0, s = 0, l = 0;
h = (RandomObject.Next(1, 2) % 2 == 0) ? RandomObject.Next(0, 180) : iApp.RandomObject.Next(181, 360);
s = RandomObject.Next(90, 160);
l = RandomObject.Next(80, 130);
return System.Drawing.ColorTranslator.FromWin32(ColorHLSToRGB(h, l, s)).ToHex();
}
private static string ToHex(this System.Drawing.Color c)
{
return "#" + c.R.ToString("X2") + c.G.ToString("X2") + c.B.ToString("X2");
}
You can replace RandomObject
with your own Random
class object.
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 needed the same functionality, in a simple form.
What I needed was to generate as unique as possible colors from an an increasing index value.
Here is the code, in C# (Any other language implementation should be very similar)
The mechanism is very simple
A pattern of color_writers get generated from indexA values from 0 to 7.
For indices < 8, those colors are = color_writer[indexA] * 255.
For indices between 8 and 15, those colors are = color_writer[indexA] * 255 + (color_writer[indexA+1]) * 127
For indices between 16 and 23, those colors are = color_writer[indexA] * 255 + (color_writer[indexA+1]) * 127 + (color_writer[indexA+2]) * 63
And so on:
private System.Drawing.Color GetRandColor(int index)
{
byte red = 0;
byte green = 0;
byte blue = 0;
for (int t = 0; t <= index / 8; t++)
{
int index_a = (index+t) % 8;
int index_b = index_a / 2;
//Color writers, take on values of 0 and 1
int color_red = index_a % 2;
int color_blue = index_b % 2;
int color_green = ((index_b + 1) % 3) % 2;
int add = 255 / (t + 1);
red = (byte)(red+color_red * add);
green = (byte)(green + color_green * add);
blue = (byte)(blue + color_blue * add);
}
Color color = Color.FromArgb(red, green, blue);
return color;
}
Note: To avoid generating bright and hard to see colors (in this example: yellow on white background) you can modify it with a recursive loop:
int skip_index = 0;
private System.Drawing.Color GetRandColor(int index)
{
index += skip_index;
byte red = 0;
byte green = 0;
byte blue = 0;
for (int t = 0; t <= index / 8; t++)
{
int index_a = (index+t) % 8;
int index_b = index_a / 2;
//Color writers, take on values of 0 and 1
int color_red = index_a % 2;
int color_blue = index_b % 2;
int color_green = ((index_b + 1) % 3) % 2;
int add = 255 / (t + 1);
red = (byte)(red + color_red * add);
green = (byte)(green + color_green * add);
blue = (byte)(blue + color_blue * add);
}
if(red > 200 && green > 200)
{
skip_index++;
return GetRandColor(index);
}
Color color = Color.FromArgb(red, green, blue);
return color;
}