Gere colors RGB distintamente diferentes em charts

Ao gerar charts e mostrar diferentes conjuntos de dados, geralmente é uma boa ideia diferenciar os conjuntos por cor. Então uma linha é vermelha e a próxima é verde e assim por diante. O problema é que, quando o número de conjuntos de dados é desconhecido, é necessário gerar aleatoriamente essas colors e, muitas vezes, elas ficam muito próximas uma da outra (verde, verde claro, por exemplo).

Alguma idéia de como isso poderia ser resolvido e como seria possível gerar colors distintas?

Eu seria ótimo se algum exemplo (sinta-se livre para discutir o problema e a solução sem exemplos, se achar mais fácil) em colors C # e RGB.

Você tem três canais de cor de 0 a 255 R, G e B.

Primeiro passar

0, 0, 255 0, 255, 0 255, 0, 0 

Então atravesse

 0, 255, 255 255, 0, 255 255, 255, 0 

Em seguida, divida por 2 => 128 e comece de novo:

 0, 0, 128 0, 128, 0 128, 0, 0 0, 128, 128 128, 0, 128 128, 128, 0 

Divida por 2 => 64

Da próxima vez, adicione 64 a 128 => 192

Siga o padrão.

Simples de programar e dá-lhe colors bastante distintas.

EDIT: Pedido de amostra de código

Além disso – adicionando o padrão adicional como abaixo, se o cinza for uma cor aceitável:

 255, 255, 255 128, 128, 128 

Existem várias maneiras de gerenciá-las no código.

O caminho fácil

Se você puder garantir que nunca precisará de mais do que um número fixo de colors, apenas gere uma matriz de colors seguindo este padrão e use-as:

  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", }; 

O jeito difícil

Se você não souber quantas colors precisará, o código abaixo gerará até 896 colors usando esse padrão. (896 = 256 * 7/2) 256 é o espaço de colors por canal, temos 7 padrões e paramos antes de chegarmos às colors separadas por apenas 1 valor de cor.

Eu provavelmente fiz um trabalho mais difícil deste código do que eu precisava. Primeiro, há um gerador de intensidade que começa em 255 e gera os valores conforme o padrão descrito acima. O gerador de padrões apenas percorre os sete padrões de colors.

 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; } } } } 

Para implementar uma lista de variação em que, por suas colors, use 255 todas as possibilidades, adicione 0 e todos os padrões RGB com esses dois valores. Em seguida, adicione 128 e todas as combinações RGB com elas. Então 64. Então 192. Etc.

Em 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; } 

Isso produzirá padrões desse tipo infinitamente (2 ^ 24) no futuro. No entanto, depois de uma centena de pontos, você provavelmente não verá muita diferença entre uma cor com 0 ou 32 no lugar do azul.

Talvez seja melhor normalizá-lo em um espaço de colors diferente. LAB color space por exemplo com os valores L, A, B normalizados e convertidos. Assim, a distinção da cor é empurrada através de algo mais parecido com o olho humano.

getElement () inverte o endian de um número de 8 bits e começa a contar de -1 em vez de 0 (mascarando com 255). Então vai 255,0,127,192,64, ... conforme o número cresce, ele move menos e menos bits significativos, subdividindo o número.

getPattern () determina qual deve ser o elemento mais significativo no padrão (é a raiz cúbica). Em seguida, prossegue para quebrar os 3N² + 3N + 1 padrões diferentes que envolvem o elemento mais significativo.

Este algoritmo produzirá (primeiros 128 valores):

 #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 

Leia da esquerda para a direita, de cima para baixo. 729 colors (9³). Então, todos os padrões até n = 9. Você notará a velocidade com a qual eles começam a colidir. Há apenas tantas variações do WRGBCYMK. E essa solução, embora inteligente, basicamente faz apenas diferentes tons de colors primárias.

Grade de cores, 729 16x16

Grande parte do conflito se deve ao verde e à forma como a maioria dos greens se parece com a maioria das pessoas. A demanda de que cada um seja maximamente diferente no início e não apenas diferente o suficiente para não ser da mesma cor. E falhas básicas na ideia, resultando em padrões de colors primárias e matizes idênticos.


Usando o CIELab2000 Color Space e Distance Routine para selecionar aleatoriamente e experimentar 10k colors diferentes e encontrar a distância mínima ao máximo distante das colors anteriores, (praticamente a definição da solicitação) evita confrontos maiores que a solução acima:

Distância de cor máxima

Que poderia ser chamado apenas de uma lista estática para o Easy Way. Demorou uma hora e meia para gerar 729 inputs:

 #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 

Usando força bruta para (testando todas as 16.777.216 colors RGB através do CIELab Delta2000 / Iniciando com preto) produz uma série. Que começa a colidir em torno de 26, mas pode chegar a 30 ou 40 com inspeção visual e queda manual (o que não pode ser feito com um computador). Portanto, fazer o máximo absoluto pode, de forma programática, fazer apenas algumas dúzias de colors distintas. Uma lista discreta é sua melhor aposta. Você obterá colors mais distintas com uma lista do que programaticamente. A maneira mais fácil é a melhor solução, comece a misturar e combine com outras maneiras de alterar seus dados do que a cor.

Maximamente Diferente

 #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 

Atualização: Eu continuei isso por cerca de um mês, a 1024 de força bruta. 1024

 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", "#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" }; 

Eu coloquei uma página online para gerar processualmente colors visualmente distintas:
http://phrogz.net/css/distinct-colors.html

Ao contrário de outras respostas aqui que percorrem uniformemente o espaço RGB ou HSV (onde há uma relação não linear entre os valores do eixo e as diferenças perceptivas ), minha página usa o algoritmo de distância de colors CMI (I: c) para evitar que duas colors sejam visualmente perto.

A guia final da página permite classificar os valores de várias maneiras e, em seguida, intercalá-los (ordem aleatória) para que você obtenha colors muito distintas colocadas próximas uma da outra.

Até o momento, ele só funciona bem no Chrome e no Safari, com um shim para o Firefox; Ele usa controles deslizantes de input de intervalo HTML5 na interface, que o IE9 e o Firefox ainda não suportam nativamente.

Eu acho que o espaço HSV (ou HSL) tem mais oportunidades aqui. Se você não se importa com a conversão extra, é muito fácil passar por todas as colors apenas girando o valor da Matiz. If that’s not enough, you can change the Saturation/Value/Lightness values and go through the rotation again. Or, you can always shift the Hue values or change your “stepping” angle and rotate more times.

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 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

  1. A pattern of color_writers get generated from indexA values from 0 to 7.

  2. For indices < 8, those colors are = color_writer[indexA] * 255.

  3. For indices between 8 and 15, those colors are = color_writer[indexA] * 255 + (color_writer[indexA+1]) * 127

  4. 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:

Rand Color Generator

  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; } 

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.

I implemented this algorithm in a shorter way

 void ColorValue::SetColorValue( double r, double g, double b, ColorType myType ) { this->c[0] = r; this->c[1] = g; this->c[2] = b; this->type = myType; } DistinctColorGenerator::DistinctColorGenerator() { mFactor = 255; mColorsGenerated = 0; mpColorCycle = new ColorValue[6]; mpColorCycle[0].SetColorValue( 1.0, 0.0, 0.0, TYPE_RGB); mpColorCycle[1].SetColorValue( 0.0, 1.0, 0.0, TYPE_RGB); mpColorCycle[2].SetColorValue( 0.0, 0.0, 1.0, TYPE_RGB); mpColorCycle[3].SetColorValue( 1.0, 1.0, 0.0, TYPE_RGB); mpColorCycle[4].SetColorValue( 1.0, 0.0, 1.0, TYPE_RGB); mpColorCycle[5].SetColorValue( 0.0, 1.0, 1.0, TYPE_RGB); } //---------------------------------------------------------- ColorValue DistinctColorGenerator::GenerateNewColor() { int innerCycleNr = mColorsGenerated % 6; int outerCycleNr = mColorsGenerated / 6; int cycleSize = pow( 2, (int)(log((double)(outerCycleNr)) / log( 2.0 ) ) ); int insideCycleCounter = outerCycleNr % cyclesize; if ( outerCycleNr == 0) { mFactor = 255; } else { mFactor = ( 256 / ( 2 * cycleSize ) ) + ( insideCycleCounter * ( 256 / cycleSize ) ); } ColorValue newColor = mpColorCycle[innerCycleNr] * mFactor; mColorsGenerated++; return newColor; } 

You could also think of the color space as all combinations of three numbers from 0 to 255, inclusive. That’s the base-255 representation of a number between 0 and 255^3, forced to have three decimal places (add zeros on to the end if need be.)

So to generate x number of colors, you’d calculate x evenly spaced percentages, 0 to 100. Get numbers by multiplying those percentages by 255^3, convert those numbers to base 255, and add zeros as previously mentioned.

Base conversion algorithm, for reference (in pseudocode that’s quite close to C#):

 int num = (number to convert); int baseConvert = (desired base, 255 in this case); (array of ints) nums = new (array of ints); int x = num; double digits = Math.Log(num, baseConvert); //or ln(num) / ln(baseConvert) int numDigits = (digits - Math.Ceiling(digits) == 0 ? (int)(digits + 1) : (int)Math.Ceiling(digits)); //go up one if it turns out even for (int i = 0; i < numDigits; i++) { int toAdd = ((int)Math.Floor(x / Math.Pow((double)convertBase, (double)(numDigits - i - 1)))); //Formula for 0th digit: d = num / (convertBase^(numDigits - 1)) //Then subtract (d * convertBase^(numDigits - 1)) from the num and continue nums.Add(toAdd); x -= toAdd * (int)Math.Pow((double)convertBase, (double)(numDigits - i - 1)); } return nums; 

You might also have to do something to bring the range in a little bit, to avoid having white and black, if you want. Those numbers aren't actually a smooth color scale, but they'll generate separate colors if you don't have too many.

This question has more on base conversion in .NET.

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 

You could get a random set of your 3 255 values and check it against the last set of 3 values, making sure they are each at least X away from the old values before using them.

OLD: 190, 120, 100

NEW: 180, 200, 30

If X = 20, then the new set would be regenerated again.