When plotting a set of lines, you may want to distinguish them by color. By default, Matlab chooses a small set of colors and cycles among them, and so if you have more than a few lines there will be confusion about which line is which. To fix this problem, one would want to be able to pick a much larger set of distinct colors, where the number of colors equals or exceeds the number of lines you want to plot. Because our ability to distinguish among colors has limits, one should choose these colors to be "maximally perceptually distinguishable."
This function generates a set of colors which are distinguishable by reference to the "Lab" color space, which more closely matches human color perception than RGB. Given an initial large list of possible colors, it iteratively chooses the entry in the list that is farthest (in Lab space) from all previously-chosen entries.
I have ported this algorithm to Python and wrote another program to take the distinguishable_colors output and a label adjacency matrix to group colors as part of the mindboggle.info brain image software project:
Thank you for writinig this, it does generate an interesting set of colors that do appear to be contrasting. Would it be possible to generate one, or more, "key" colors that are highly contasted with the rest. I have about 30 lines on a figure, along with the average. While I did make the average wider, it is difficult to determine the color for the "key" line(s) using this routine.
@Robert Daly: sorry I didn't see your question earlier. It's an interesting application.
I'm no expert at these matters, but I imagine you could convert to LMS color space and then set one or more of the components to zero. You'd probably then want to convert back to Lab to judge perceptual distinguishability.
Alternatively (and perhaps more guaranteed to be accurate), you could use this lookup table:
and then convert the modified RGB values to Lab.
If you implement this, I'd be curious to see what the final result looks like.
Is there a colour space function that I could use with this function to find colours that are perceptually-distinct to a person with a colour vision deficiency (colour blind)? In the example I have in mind colours that are only different by the amount of red in them such as blue and purple look the same (Protanopia).
Excellent idea. I have one suggestion. Often times, I want to avoid not just a single background color but a set of them. For example both black and white when I have black text on white background already.
This works very well. If you are using an older version of MatLab, you will need to modify line 98
[~,index] = max(mindist2);
as the ~ operator will produce an error. Simply change it to junk for example.
Thanks for the feedback and suggestions, everyone. Perhaps even more important than the issue of depending on the Image Processing Toolbox, you helped me realize that there's no particular reason to restrict this to Lab colorspace; one can easily envision scenarios where the user would like to be able to have some control over what is considered "perceptually similar." So I have uploaded a new version that allows the user to supply his/her own function that converts RGB colors into whatever space "similarity" is to be judged in. Of course, one effect is that this will allow you to use the "colorspace" function.
From the description is seems to be one of the functions that I have been looking for many times, and the excellent rating from Brett only wettens my appetite. Alas, I do not have the image processing toolbox. Would it be possible to instead use this FEX contribution:
Very nicely done...well written, solid, useful code.
14 Dec 2010
I have added the option for the user to supply a function handle to any desired colorspace conversion function. One application is to use the file exchange's "colorspace" set of tools. In this case, you no longer need the image processing toolbox.
07 Feb 2011
As suggested by Il, I added the ability to avoid multiple background colors.