devxlogo

Generating a Series of Unique Colors

Generating a Series of Unique Colors

Graphs, charts, and maps often use color to help the user tell data points apart. For instance, a line graph comparing processor benchmarks might show the Motorola processor in red, the Intel processor in blue, the Sun processor in green, and so on. For small, fixed data sets (about 10 or less), there’s no problem in specifying the color coding at compile time in order to get the right look and to ensure that the colors are unique. But what if the data sets are neither small nor fixed? For instance, let’s say you could have anywhere from 2 to 50 data sets, and you won’t know exactly how many sets there will be until the program actually runs. Surely there exists some algorithm that could choose the color coding for you–at run time–and choose it in such a way that the colors are as unique and easy to distinguish as possible.

I pondered this problem and wasted a few hours trying to figure out how to iterate through red, green, and blue values to get an even distribution of unique colors. Then, as I was playing around with the Color Chooser component of the Swing framework, I happened to notice that the HSB panel (hue, saturation, and brightness) of the chooser displayed exactly what I was trying to create: a rainbow of colors. It showed a brightly colored bar that gradually changed from red, to yellow, to green, to cyan, to blue, and to violet. Upon closer inspection, I realized that the bar had not been generated through some complex algorithm, but merely by iterating through the range of possible values for the hue.

With this information in hand, I was able to create a color generation algorithm. This algorithm creates an array of unique, evenly distributed colors by keeping the saturation and brightness levels constant while sliding the hue level. On each iteration of the loop, it passes these values to the Color.getHSBColor() method which returns a standard java.awt.Color object representing those levels. Notice that although the true range of the hue level goes from 0.0 to 1.0, I have adjusted the range in the algorithm to go from 0.0 to 0.85. This eliminates the problem of similar colors due to the wrapping of the color spectrum. Also, because the spectrum of hue levels gives extra space to red, blue, and green values, I have hacked the algorithm to alternate between light and dark versions of the same hue, producing a more fully distributed range of colors. For these reasons, the algorithm isn’t perfect, but it works well enough for most purposes.

 /**Generates a series of colors such that thedistribution of the colors is (fairly) evenly spacedthroughout the color spectrum. This is especiallyuseful for generating unique color codes to be usedin a legend or on a graph.@param numColors the number of colors to generate@return an array of Color objects representing thecolors in the table*/private Color[] createColorCodeTable(int numColors){   Color[] table = new Color[numColors];   if (numColors == 1)   {      // Special case for only one color      table[0] = Color.red;   }   else   {      float hueMax = (float) 0.85;      float sat = (float) 0.8;      for (int i = 0; i < numColors; i++)      {         float hue = hueMax * i / (numColors-1);         // Here we interleave light colors and dark colors         // to get a wider distribution of colors.         if (i % 2 == 0)            table[i] = Color.getHSBColor(hue, sat, (float)0.9);         else            table[i] = Color.getHSBColor(hue, sat, (float)0.7);      }   }   return table;}
devxblackblue

About Our Editorial Process

At DevX, we’re dedicated to tech entrepreneurship. Our team closely follows industry shifts, new products, AI breakthroughs, technology trends, and funding announcements. Articles undergo thorough editing to ensure accuracy and clarity, reflecting DevX’s style and supporting entrepreneurs in the tech sphere.

See our full editorial policy.

About Our Journalist