<p>This is something I've pseudo-solved many times and have never quite found a solution for.</p>

<p>The problem is to come up with a way to generate <code>N</code> colors, that are as distinguishable as possible where <code>N</code> is a parameter.</p>

[{'answer_id': 199, 'author': 'helloandre', 'author_id': 50, 'author_profile': 'https://Stackoverflow.com/users/50', 'pm_score': 2, 'selected': False, 'text': "<p>I've read somewhere the human eye can't distinguish between less than 4 values apart. so This is something to keep in mind. The following algorithm does not compensate for this.</p>\n\n<p>I'm not sure this is exactly what you want, but this is one way to randomly generate non-repeating color values:</p>\n\n<p>(beware, inconsistent pseudo-code ahead)</p>\n\n<pre><code>//colors entered as 0-255 [R, G, B]\ncolors = []; //holds final colors to be used\nrand = new Random();\n\n//assumes n is less than 16,777,216\nrandomGen(int n){\n   while (len(colors) &lt; n){\n      //generate a random number between 0,255 for each color\n      newRed = rand.next(256);\n      newGreen = rand.next(256);\n      newBlue = rand.next(256);\n      temp = [newRed, newGreen, newBlue];\n      //only adds new colors to the array\n      if temp not in colors {\n         colors.append(temp);\n      }\n   }\n}\n</code></pre>\n\n<p>One way you could optimize this for better visibility would be to compare the distance between each new color and all the colors in the array:</p>\n\n<pre><code>for item in color{\n   itemSq = (item[0]^2 + item[1]^2 + item[2]^2])^(.5);\n   tempSq = (temp[0]^2 + temp[1]^2 + temp[2]^2])^(.5);\n   dist = itemSq - tempSq;\n   dist = abs(dist);\n}\n//NUMBER can be your chosen distance apart.\nif dist &lt; NUMBER and temp not in colors {\n   colors.append(temp);\n}\n</code></pre>\n\n<p>But this approach would significantly slow down your algorithm.</p>\n\n<p>Another way would be to scrap the randomness and systematically go through every 4 values and add a color to an array in the above example.</p>\n"}, {'answer_id': 529, 'author': 'svrist', 'author_id': 86, 'author_profile': 'https://Stackoverflow.com/users/86', 'pm_score': 3, 'selected': False, 'text': '<p>Isn\'t it also a factor which order you set up the colors?</p>\n\n<p>Like if you use Dillie-Os idea you need to mix the colors as much as possible. \n0 64 128 256 is from one to the next. but 0 256 64 128 in a wheel would be more "apart"</p>\n\n<p>Does this make sense?</p>\n'}, {'answer_id': 539, 'author': 'nlucaroni', 'author_id': 157, 'author_profile': 'https://Stackoverflow.com/users/157', 'pm_score': 6, 'selected': True, 'text': '<p>My first thought on this is "how to generate N vectors in a space that maximize distance from each other."</p>\n\n<p>You can see that the RGB (or any other scale you use that forms a basis in color space) are just vectors. Take a look at <a href="http://mathworld.wolfram.com/topics/RandomPointPicking.html" rel="noreferrer">Random Point Picking</a>. Once you have a set of vectors that are maximized apart, you can save them in a hash table or something for later, and just perform random rotations on them to get all the colors you desire that are maximally apart from each other!</p>\n\n<p>Thinking about this problem more, it would be better to map the colors in a linear manner, possibly (0,0,0) → (255,255,255) lexicographically, and then distribute them evenly.</p>\n\n<p>I really don\'t know how well this will work, but it should since, let us say:</p>\n\n<pre><code>n = 10\n</code></pre>\n\n<p>we know we have 16777216 colors (256^3).</p>\n\n<p>We can use <a href="https://stackoverflow.com/questions/561/using-combinations-of-sets-as-test-data#794">Buckles Algorithm 515</a> to find the lexicographically indexed color.<img src="https://i.stack.imgur.com/gEuCs.gif" alt="\\frac {\\binom {256^3} {3}} {n} * i">. You\'ll probably have to edit the algorithm to avoid overflow and probably add some minor speed improvements.</p>\n'}, {'answer_id': 59760, 'author': 'Liudvikas Bukys', 'author_id': 5845, 'author_profile': 'https://Stackoverflow.com/users/5845', 'pm_score': 4, 'selected': False, 'text': '<p>It would be best to find colors maximally distant in a "perceptually uniform" colorspace, e.g. CIELAB (using Euclidean distance between L*, a*, b* coordinates as your distance metric) and then converting to the colorspace of your choice.  Perceptual uniformity is achieved by tweaking the colorspace to approximate the non-linearities in the human visual system.</p>\n'}, {'answer_id': 93908, 'author': 'hadley', 'author_id': 16632, 'author_profile': 'https://Stackoverflow.com/users/16632', 'pm_score': 4, 'selected': False, 'text': '<p>Some related resources:</p>\n\n<p><a href="http://colorbrewer.org" rel="noreferrer">ColorBrewer</a> - Sets of colours designed to be maximally distinguishable for use on maps.</p>\n\n<p><a href="http://epub.wu-wien.ac.at/dyn/openURL?id=oai:epub.wu-wien.ac.at:epub-wu-01_c87" rel="noreferrer">Escaping RGBland: Selecting Colors for Statistical Graphics</a> - A technical report describing a set of algorithms for generating good (i.e. maximally distinguishable) colour sets in the hcl colour space.</p>\n'}, {'answer_id': 143966, 'author': 'ravenspoint', 'author_id': 16582, 'author_profile': 'https://Stackoverflow.com/users/16582', 'pm_score': 3, 'selected': False, 'text': '<p>Here is some code to allocate RGB colors evenly around a HSL color wheel of specified luminosity.</p>\n\n<pre><code>class cColorPicker\n{\npublic:\n    void Pick( vector&lt;DWORD&gt;&amp;v_picked_cols, int count, int bright = 50 );\nprivate:\n    DWORD HSL2RGB( int h, int s, int v );\n    unsigned char ToRGB1(float rm1, float rm2, float rh);\n};\n/**\n\n  Evenly allocate RGB colors around HSL color wheel\n\n  @param[out] v_picked_cols  a vector of colors in RGB format\n  @param[in]  count   number of colors required\n  @param[in]  bright  0 is all black, 100 is all white, defaults to 50\n\n  based on Fig 3 of http://epub.wu-wien.ac.at/dyn/virlib/wp/eng/mediate/epub-wu-01_c87.pdf?ID=epub-wu-01_c87\n\n*/\n\nvoid cColorPicker::Pick( vector&lt;DWORD&gt;&amp;v_picked_cols, int count, int bright )\n{\n    v_picked_cols.clear();\n    for( int k_hue = 0; k_hue &lt; 360; k_hue += 360/count )\n        v_picked_cols.push_back( HSL2RGB( k_hue, 100, bright ) );\n}\n/**\n\n  Convert HSL to RGB\n\n  based on http://www.codeguru.com/code/legacy/gdi/colorapp_src.zip\n\n*/\n\nDWORD cColorPicker::HSL2RGB( int h, int s, int l )\n{\n    DWORD ret = 0;\n    unsigned char r,g,b;\n\n    float saturation = s / 100.0f;\n    float luminance = l / 100.f;\n    float hue = (float)h;\n\n    if (saturation == 0.0) \n    {\n      r = g = b = unsigned char(luminance * 255.0);\n    }\n    else\n    {\n      float rm1, rm2;\n\n      if (luminance &lt;= 0.5f) rm2 = luminance + luminance * saturation;  \n      else                     rm2 = luminance + saturation - luminance * saturation;\n      rm1 = 2.0f * luminance - rm2;   \n      r   = ToRGB1(rm1, rm2, hue + 120.0f);   \n      g = ToRGB1(rm1, rm2, hue);\n      b  = ToRGB1(rm1, rm2, hue - 120.0f);\n    }\n\n    ret = ((DWORD)(((BYTE)(r)|((WORD)((BYTE)(g))&lt;&lt;8))|(((DWORD)(BYTE)(b))&lt;&lt;16)));\n\n    return ret;\n}\n\n\nunsigned char cColorPicker::ToRGB1(float rm1, float rm2, float rh)\n{\n  if      (rh &gt; 360.0f) rh -= 360.0f;\n  else if (rh &lt;   0.0f) rh += 360.0f;\n\n  if      (rh &lt;  60.0f) rm1 = rm1 + (rm2 - rm1) * rh / 60.0f;   \n  else if (rh &lt; 180.0f) rm1 = rm2;\n  else if (rh &lt; 240.0f) rm1 = rm1 + (rm2 - rm1) * (240.0f - rh) / 60.0f;      \n\n  return static_cast&lt;unsigned char&gt;(rm1 * 255);\n}\n\nint _tmain(int argc, _TCHAR* argv[])\n{\n    vector&lt;DWORD&gt; myCols;\n    cColorPicker colpick;\n    colpick.Pick( myCols, 20 );\n    for( int k = 0; k &lt; (int)myCols.size(); k++ )\n        printf("%d: %d %d %d\\n", k+1,\n        ( myCols[k] &amp; 0xFF0000 ) &gt;&gt;16,\n        ( myCols[k] &amp; 0xFF00 ) &gt;&gt;8,\n        ( myCols[k] &amp; 0xFF ) );\n\n    return 0;\n}\n</code></pre>\n'}, {'answer_id': 7815745, 'author': 'Mauro', 'author_id': 678455, 'author_profile': 'https://Stackoverflow.com/users/678455', 'pm_score': 2, 'selected': False, 'text': "<pre><code>function random_color($i = null, $n = 10, $sat = .5, $br = .7) {\n    $i = is_null($i) ? mt_rand(0,$n) : $i;\n    $rgb = hsv2rgb(array($i*(360/$n), $sat, $br));\n    for ($i=0 ; $i&lt;=2 ; $i++) \n        $rgb[$i] = dechex(ceil($rgb[$i]));\n    return implode('', $rgb);\n}\n\nfunction hsv2rgb($c) { \n    list($h,$s,$v)=$c; \n    if ($s==0) \n        return array($v,$v,$v); \n    else { \n        $h=($h%=360)/60; \n        $i=floor($h); \n        $f=$h-$i; \n        $q[0]=$q[1]=$v*(1-$s); \n        $q[2]=$v*(1-$s*(1-$f)); \n        $q[3]=$q[4]=$v; \n        $q[5]=$v*(1-$s*$f); \n        return(array($q[($i+4)%6]*255,$q[($i+2)%6]*255,$q[$i%6]*255)); //[1] \n    } \n}\n</code></pre>\n<p>So just call the <code>random_color()</code> function where <code>$i</code> identifies the color, <code>$n</code> the number of possible colors, <code>$sat</code> the saturation and <code>$br</code> the brightness.</p>\n"}, {'answer_id': 21634390, 'author': 'Adi Shavit', 'author_id': 135862, 'author_profile': 'https://Stackoverflow.com/users/135862', 'pm_score': 2, 'selected': False, 'text': '<p>To achieve &quot;most distinguishable&quot; we need to use a perceptual color space like Lab (or any other perceptually linear color space) other than RGB. Also, we can quantize this space to reduce the size of the space.</p>\n<p>Generate the full 3D space with all possible quantized entries and run the K-means algorithm with <code>K=N</code>. The resulting centers/&quot;means&quot; should be approximately most distinguishable from each other.</p>\n'}]
['https://Stackoverflow.com/questions/180', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/2089740/']