c# random graph colors

c# - Generar colores RGB claramente diferentes en gráficos



random graph (11)

He puesto una página en línea para generar procedimientos visualmente distintos colores:
http://phrogz.net/css/distinct-colors.html

A diferencia de otras respuestas aquí que cruzan uniformemente el espacio RGB o HSV (donde hay una relación no lineal entre los valores del eje y las diferencias de percepción ), mi página utiliza el algoritmo de distancia de color CMI(I:c) estándar para evitar que dos colores sean demasiado visualmente cerca.

La pestaña final de la página le permite ordenar los valores de varias maneras y luego intercalarlos (orden aleatorio) para que obtenga colores muy distintos colocados uno al lado del otro.

Al momento de escribir esto, solo funciona bien en Chrome y Safari, con un complemento para Firefox; utiliza controles deslizantes de entrada de rango HTML5 en la interfaz, que IE9 y Firefox aún no admiten de forma nativa.

Al generar gráficos y mostrar diferentes conjuntos de datos, generalmente es una buena idea diferenciar los conjuntos por color. Entonces una línea es roja y la siguiente es verde y así sucesivamente. El problema es que cuando se desconoce el número de conjuntos de datos, uno necesita generar aleatoriamente estos colores y, a menudo, terminan muy cerca el uno del otro (verde, verde claro, por ejemplo).

¿Alguna idea sobre cómo se podría resolver esto y cómo sería posible generar colores claramente diferentes?

Sería grandioso si algún ejemplo (siéntase libre de solo discutir el problema y la solución sin ejemplos si lo encuentra más fácil) estuviera en colores basados ​​en C # y RGB.


Para implementar una lista de variación donde vayan los colores, 255 luego use todas las posibilidades de eso, luego agregue 0 y todos los patrones RGB con esos dos valores. A continuación, agregue 128 y todas las combinaciones RGB con esas. Entonces 64. Luego 192. Etc.

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

Esto producirá patrones de ese tipo infinitamente (2 ^ 24) en el futuro. Sin embargo, después de un centenar de manchas, es probable que no vea mucha diferencia entre un color con 0 o 32 en lugar de azul.

Tal vez sea mejor que lo normalice en un espacio de color diferente. Espacio de color LAB por ejemplo con los valores L, A, B normalizados y convertidos. Entonces, la distinción del color es empujada a través de algo más parecido al ojo humano.

getElement () invierte el endian de un número de 8 bits y comienza a contar desde -1 en lugar de 0 (máscara con 255). Entonces va 255,0,127,192,64, ... a medida que el número crece, mueve cada vez menos bits significativos, subdividiendo el número.

getPattern () determina cuál debe ser el elemento más significativo en el patrón (es la raíz del cubo). Luego procede a descomponer los 3N² + 3N + 1 patrones diferentes que involucran ese elemento más significativo.

Este algoritmo producirá (primeros 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

Leer de izquierda a derecha, de arriba a abajo. 729 colores (9³). Entonces todos los patrones hasta n = 9. Notarán la velocidad a la que comienzan a chocar. Hay muchas variaciones de WRGBCYMK. Y esta solución, aunque inteligente, básicamente solo hace diferentes tonos de colores primarios.

Gran parte del choque se debe al verde y cuán similar es la mayoría de los verdes para la mayoría de las personas. La demanda de que cada uno sea al máximo diferente al inicio en lugar de simplemente lo suficientemente diferente como para no ser del mismo color. Y fallas básicas en la idea que dan como resultado patrones de colores primarios y matices idénticos.

Al utilizar CIELab2000 Espacio de color y Rutina de distancia para seleccionar aleatoriamente y probar 10k colores diferentes y encontrar la distancia mínima máxima distante de los colores anteriores, (más o menos la definición de la solicitud) se evitan los enfrentamientos por más tiempo que la solución anterior:

Lo cual podría llamarse una lista estática para Easy Way. Llevó una hora y media generar 729 entradas:

#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

Usar fuerza bruta para (probar todos los 16,777,216 colores RGB a través de CIELab Delta2000 / Comenzar con negro) produce una serie. Que comienza a chocar alrededor de 26 pero podría llegar a 30 o 40 con inspección visual y caída manual (que no se puede hacer con una computadora). Así que hacer el máximo absoluto puede programáticamente solo hace un par de docenas de colores distintos. Una lista discreta es tu mejor apuesta. Obtendrá colores más discretos con una lista de la que usaría programáticamente. La manera fácil es la mejor solución, comience a mezclar y combinar con otras formas de alterar los datos que el 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

Actualización: continué esto durante aproximadamente un mes, así que a 1024 fuerza bruta.

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


Tienes tres canales de color de 0 a 255 R, G y B.

Primero pasar

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

Luego revisa

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

Luego divide por 2 => 128 y comienza de nuevo:

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

Divide por 2 => 64

La próxima vez agrega 64 a 128 => 192

seguir el modelo.

Sencillo de programar y le da colores bastante distintos.

EDITAR: solicitud de muestra de código

Además, agregue el patrón adicional de la siguiente manera si el color gris es aceptable:

255, 255, 255 128, 128, 128

Hay varias maneras en que puede manejar la generación de estos en el código.

La manera fácil

Si puede garantizar que nunca necesitará más de un número fijo de colores, solo genere una matriz de colores siguiendo este patrón y utilícelos:

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

El camino difícil

Si no sabe cuántos colores va a necesitar, el siguiente código generará hasta 896 colores usando este patrón. (896 = 256 * 7/2) 256 es el espacio de color por canal, tenemos 7 patrones y nos detenemos antes de llegar a colores separados por solo 1 valor de color.

Probablemente he hecho un trabajo más difícil de este código del que necesitaba. Primero, hay un generador de intensidad que comienza en 255, luego genera los valores según el patrón descrito anteriormente. El generador de patrones simplemente recorre los siete patrones de color.

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


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


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:

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 think the HSV (or HSL) space has more opportunities here. If you don''t mind the extra conversion, it''s pretty easy to go through all the colors by just rotating the Hue value. 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.


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.


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


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.


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.


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