Maximally Distinct Color Generator

Version 3.0.0 (450 KB) by Stephen23
Generate maximally-distinct colors in an RGB colormap.
2.2K Downloads
Updated 11 Dec 2025

View License

MAXDISTCOLOR generates an RGB colormap of maximally-distinct colors. The distance between the colors is measured in a perceptually uniform colorspace, which by default is OKLab: https://en.wikipedia.org/wiki/Oklab_color_space
Optional input arguments allow the user to:
  • Limit the lightness range.
  • Limit the chroma range.
  • Provide a colormap of colors to be excluded (e.g. background colors, existing plot colors).
  • Provide a colormap of colors to be included (e.g. company colorscheme).
  • Specify the class (double/single) used for the RGB calculations.
  • Specify the bit/color depth to control the number of samples of each color channel.
  • Sort the colormap (e.g. by hue, chroma, saturation, lightness, farthest colors, etc.).
  • Use a different perceptually uniform colorspace.
See the Examples tab (HTML documentation) for explanations of the required and optional input arguments.
Warning
Requesting many colors from a large gamut can require minutes/hours/days of processing. Some option combinations are not tractable!
Examples
>> N = 5;
>> rgb = maxdistcolor(N)
rgb =
0 0 0.80952
1 0.38583 0
0.8254 0 1
0.42857 0 0.015873
0 0.8189 0
>> axes('ColorOrder',rgb, 'NextPlot','replacechildren')
>> X = linspace(0,pi*3,1000);
>> Y = bsxfun(@(x,n)n*sin(x+2*n*pi/N), X(:), 1:N);
>> plot(X,Y, 'linewidth',4)
>> maxdistcolor(5, 'exc',[0,0,0]) % Exclude only black.
ans =
1 1 1
0 0 1
0 0.67717 0
1 0.19685 1
0.52381 0 0.063492
>> maxdistcolor(5, 'inc',[1,0,1]) % Include magenta.
ans =
1 0 1 <- magenta!
0 0.85827 0
0.11111 0 1
0 0.26772 0
0.8254 0.38583 0
>> [rgb,Lab] = maxdistcolor(6, 'Lmin',0.5, 'Lmax',0.7)
rgb =
0.42857 0 0.96825
0 0.74803 0
1 0 0.15873
0 0.65354 1
0.39683 0.40157 0.30159
1 0 0.98413
Lab =
0.50226 0.093312 -0.27038
0.69651 -0.18804 0.14423
0.6297 0.23078 0.10984
0.69962 -0.076203 -0.15295
0.50336 -0.013163 0.036171
0.6993 0.27502 -0.1638
Motivation
The development of MAXDISTCOLOR was prompted by:
  1. Existing "distinct color" generators use inadequate colorspaces and/or algorithms, leading to suboptimal color distinctiveness.
  2. The realization that 64 bit PCs with >8 GB of RAM can operate on the entire 16 million colors of 24 bit TrueColor, allowing for neat and simple vectorized MATLAB code.
These two motivations are closely linked to two non-trivial tasks that have to be solved in order to generate maximally-distinct colors:
  1. An algorithm to find the best color combination requires finding the global optimum, a task which grows exponentially with the number of requested colors and with the color gamut size. In MAXDISTCOLOR I use repeated application of a simple greedy algorithm to find the maximally-distinct colors: the repeated greedy algorithm is not particularly fast and is not a general solution for finding a global optimum, but luckily it gives good results for the regularly sampled RGB cube. Note that this algorithm contains no random numbers: it is entirely deterministic and repeatable.
  2. Defining a true uniform colorspace: the venerable CIELab (used by most existing tools I could find) is not really very uniform, particularly around the blues/greens. For MAXDISTCOLOR I used OKLab, a very neat perceptually uniform colorspace with a relatively simple implementation.

Cite As

Stephen23 (2026). Maximally Distinct Color Generator (https://nl.mathworks.com/matlabcentral/fileexchange/70215-maximally-distinct-color-generator), MATLAB Central File Exchange. Retrieved .

MATLAB Release Compatibility
Created with R2010b
Compatible with R2009b and later releases
Platform Compatibility
Windows macOS Linux
Version Published Release Notes
3.0.0

* Use inbuilt OKLab by default.
* Remove 2nd input argument.

2.6.0

* Improve error message handling.
* Add saturation sort.
* Remove Pause/Eval button from VIEW, improve UIX.
* 2nd attempt at compatibilty with R2025a (work in progress).

2.5.1

* Improve error message handling.
* Move colorspace identification to conversion functions.
* 1st attempt at compatibilty with R2025a (work in progress).

2.5.0

- VIEW: remove alphashape, improve pointcloud.
- sRGB conversion functions: document XYZ,etc. optional input arguments.
- DIN99: integrate sRGB conversion and all DIN99 variants into one function.
- OSAUCS: fix scale bug (Ymax 1->100).

2.4.4

* Improve FEX & HTML descriptions

2.4.3

* Improve options parsing.
* Add "class" option.

2.4.2

* Colorspace detection moved to within the main function.
* Improved HTML documentation.
* Improved display text.
* Improved status output distance calculation.

2.4.1

* Minor edits to help and documentation.

2.4.0

* Add OKLab colorspace conversion function.
* Add test functions for all colorspace conversions.
* Improve <Cmax>&<Cmin> filter.
* Improve <disp> text.
* Change default <exc> value to [0,0,0;1,1,1].
* Standard matrix for sRGB to XYZ.

2.3.1

* Add <sort> option 'chroma'.
* Tweaks to HTML documentation.

2.3.0

* Text arguments can be string scalar or char vector.
* Remove integer support for INC and EXC.
* Fix INC and EXC table sizes in _VIEW.

2.2.0

* Third output is a structure of greedy algorithm status information.

2.1.3

Update image

2.1.2

Update example image.

2.1.1

* Spelling corrections.

2.1.0

* Add OSA-UCS function.
* Add pointcloud to _VIEW.
* Add error IDs.

2.0.6

* Improve FEX examples.

2.0.5

* Add error codes.

2.0.4

* Update screenshot

2.0.3

* Add DIN99 conversion function.
* Improve time display.
* Iteration limit based on reaching a stable solution.
* _VIEW: new RGB values on colorbands plot.
* _VIEW: show excluded colors in RGB cube.

2.0.2

Fix time display.

2.0.1

Add correct screenshot.

2.0.0

* Use new CIECAM02 version for documentation.
* Faster VIEW function (plot gamut only on demand).

1.2.0

Add interactive viewer function

1.1.0

Change default to [6,7,6] bits.

1.0.2

Add FEX image

1.0.1

Add links to HTML.

1.0.0