A Lab-based uniform color scale 40

Posted by Steve Eddins,

DSP Tips & Tricks

One of my favorite professional publications is IEEE Signal Processing Magazine. It has a regular feature called "DSP Tips & Tricks." In the January 2006 issue, James McNames wrote a tips & tricks article called "An Effective Color Scale for Simultaneous Color and Gray-Scale Publications." Professor McNames, of Portland State University, wrote that while "color is increasingly available for electronic publications at no additional cost ... most color scales are distored when converted to gray scale. [... This] article proposes a color scale that appears as a monotonic gray scale in printed form and significantly enhances the image resolution when viewed in color."

McNames gives four design principles for selecting an effective color scale (or colormap, in MATLAB terminology):

  • "[The] color scale should cover as much of the range of available colors as possible, subject to the constraint that the luminance increases monotonically (for gray scale publications).
  • "Neighboring colors throughout the scale should be as distinct as possible."
  • "The perceptual difference between two colors should be approximately proportional to the difference between their positions along the color scale."
  • "The color scale should be intuitive."

The article goes on to show some math and some MATLAB code for creating such a color scale. Professor McNames provides a full MATLAB implementation of the idea (ColorSpiral.m) on his web site.

A path through L*a*b* color space

The McNames article describes a method for constructing a path through RGB space that has the desired properties, at least approximately. I thought it might be conceptually simpler to form a color scale by constructing a path through a different color space, L*a*b*. This color space separates luminance, L*, from two color difference components, a* and b*.

If you convert a* and b* to polar coordinates, the angle corresponds to hue, and the radius corresponds to chroma, or vividness of hue.

Let's make a color scale that is a uniform ramp in L*. In the a*-b* plane, trace a semicircular path of radius 50, with angle varying between 0 and pi/2.

radius = 50;
theta = linspace(0, pi/2, 256).';
a = radius * cos(theta);
b = radius * sin(theta);
L = linspace(0, 100, 256).';
Lab = [L, a, b];

Now convert the L*a*b* values to sRGB so we can use it as a MATLAB colormap. Use the Image Processing Toolbox functions makecform and applycform.

map = applycform(Lab, makecform('lab2srgb'));

Radon example

Let's use this colormap for looking at a Radon transform image.

I = zeros(100,100);
I(25:75, 25:75) = 1;
theta = 0:180;
[R,xp] = radon(I,theta);

Color scale function on MATLAB Central

The function color_scale on MATLAB Central lets you easily create color scales like this. You can choose different values for the radius and the starting angle, and you specify a clockwise or counterclockwise path through a*-b* space.


Color scale GUI

The same MATLAB Central submission contains the color_scale_tool function, which is a GUI that lets you control the color scale parameters with sliders. It also shows you both the color scale and the approximate grayscale equivalent. Here's a screen shot:

Give it a try.

Get the MATLAB code

Published with MATLAB® 7.2

40 CommentsOldest to Newest

colour replied on : 1 of 40

Hi Steve,

I want to change Lightness, hue and chroma of image by using slider, how should I make function for that.

COuld you explain me.


vmax replied on : 3 of 40

Hello steve,
i am final year student and i am working on project in image procssing.i am begineer to DSP. i know some basic theory of DSP. i worked on MATLAB for very small duration.
i want to convert colouring image in to B/W image.how can i do this? is it possible in MATLAB by writing some coding? if yes, then give me some example of coding.


Yori Adegun replied on : 5 of 40

Hi Steve,
i have got medical images similar to Ultrasonography in the gray scale, i want to convert them to the modified rainbow colour scale. I have never worked with MATLAB. Can i do this on MATLAB and how? Thank you.

Steve replied on : 6 of 40

Yori—You can display a grayscale image in MATLAB using any colormap you like. See the MATLAB graphics documentation for raster image display.

V Thomas replied on : 7 of 40

I would like to convert RGB colors to CIE La*b*. I would like to take the 16x16x16 bin RGB histogram of an image and convert to CIE La*b* bins. please help

Steve replied on : 8 of 40

V—You can use makecform and applycform to convert between the sRGB and L*a*b* color spaces. For computing a three-dimensional RGB histogram, you could use accumarray.

Fatimah replied on : 9 of 40

Hi Mr.Steve,

I am master student by research. I am working with color cervical images. I want to separate all colors CMYK or RGB using L*a*b* space but with 3D scatterplot.Can I do that? How? Thank you.

Steve replied on : 10 of 40

Fatimah—Use the Image Processing Toolbox functions makecform and applycform to convert to the L*a*b* color space, and then use the MATLAB function scatter3.

Ernest Miller replied on : 11 of 40

Hi Steve,

Could you explain how to use Matlab to calculate the color volume contained in a list of Lab colors? There are commercial applications that do this (XRite) but there is no documentation on how it is done and no explanation why one application, say Kodak, varies from another.

Perhaps best to build something in Matlab.

Thank you,

Steve replied on : 13 of 40

Ernest—If you mean plotting the color gamut, I don’t know how to do that. I would be interested to learn more about it.

Doug Schwarz replied on : 14 of 40


It’s easy to compute the volume in Lab space of a set of Lab colors with convhulln. Just pass in the nx3 matrix of Lab coordinates and the volume is the second output argument. However, you have to be careful about what you are comparing. It is not necessarily true that a color that is inside the convex hull is physically realizable with the system that is producing the colors (which is just another way of saying that the gamut is not convex). In that case the volume of the hull is a poor indication of the true gamut. That may be why applications vary — they are designed for use with different color systems.

Doug (former Kodaker)

Ernest Miller replied on : 16 of 40


Thank you for the response. Much appreciated!

Former Kodaker’s seem to be good fellows.


Ernest Miller replied on : 17 of 40

Hello Steve,

Regarding tetrahedral interpolation for color space conversion (Nov 24, 2006) you explain that the view is hard to see, so you show individual tetrahedra in separate plots.

Can you explain how the individual plots can represent more accurate RGBCMY colors. I changed ‘jet’ to ‘prism’ and that was much closer, but I can not tell if the color order is correct nor how to adjust each fill color closer to actual color.

Appreciate your help.


Steve replied on : 18 of 40

Ernest—The plots are simply showing faces of a tetrahedra. The colors I chose to display the faces with don’t have anything to do “real” colors.

Ernest Miller replied on : 19 of 40

Hi Steve,

Understood. However, can you explain how to change the colors?



Hi Steve-

Not exactly on topic, but you seem like the man in the know!

I have two contour plots, one with range 0-10 and the other with range 0-5. When applying the colormap it is scaled to fit the data range, but when displaying the images next to each other I want them to share the same scale, so that like colour contours match up. Is there an easy way to achieve this without messing around with the original data for the plots?

Thanks in advance,


Steve replied on : 22 of 40

Malcolm—I’m not sure exactly how you are displaying the various pieces together (one figure? multiple figures? subplots?), but you might try explicitly setting the CLim property of the axes objects involved.

It’s single figure with two filled contour plots placed using subplot. I’ll take a look at CLim and see what I can do with that. Thanks for the heads up it’s appreciated.


Herve replied on : 24 of 40

Hi Steve,

I am working on a picture obtained via an infrared camera. Each color correspond to a specific temperature (i have the colormap giving the temperature correspondance), i would like to see this picture in gray so that cold colors will be in dark and colors corresponding to hot regions will be in white. Is it possible to do it simply? (Just using rgb2gray is not a solution).
Thank you for your help!


Steve replied on : 25 of 40

Herve—Compute the gray value you would like to see for each specified color in the original, and then form a new colormap by replicating the desired gray value in each of the three columns.

Jack replied on : 26 of 40

Hello Steve,

What would be best way to visually represent a 16x16x16 RGB histogram? I was thinking of using color to represent the count in each bin a 3-dimension space. Is this the right way to go about it? If not, could you give me some cues?

Steve replied on : 27 of 40

Jack—I’m sorry, but I don’t know. I’ve never done any work with 3-D histogram visualization.

Leslie replied on : 28 of 40

I downloaded McNames ColorSpiral.m and am running it with the default parameters

cmap = ColorSpiral(64,2,0);
pcolor(time,height,numbers);shading interp

I printed B&W copies of the resulting plots and discovered that they do *not* appear to be linear in greyscale, although they’ve got only 1 internal light band compared to the 2 in “Jet”. Has anyone else found this? Does anyone understand it? I’ve written to McNames but received no response.

Steve replied on : 29 of 40

Leslie—I remember also finding that McNames’ method didn’t actually have linear grayscale appearance, but I don’t remember the details. That was one of the reasons I wanted to experiment with a Lab-based method.

Nawar replied on : 31 of 40

Hi Stave,

I am a master student working on color printing and gamut issues. I want to convert from RGB to Lab based on Adobe98 not based on sRGB. in makecform list there is not adobe just sRGB. Could you please let me know how to do that.

Thank you in advance

Steve replied on : 32 of 40

Nawar—Although makecform does not support conversions with AdobeRGB, the appropriate formulas are readily available online.

Matteo replied on : 33 of 40

Leslie, Steve

I hade the same problem.
This happens – I think – because McNames assumed gray = 1/3 r + 1/3 g + 1/3 b. I read from Matlab help online that this is not how the conversion is done if you use rgb2gray, therefore the issue. For those that like me do not have the Image Processing Toolbox, you can see this by just applying the formula that rgb2gray uses which is G=(0.2989 * R + 0.5870 * G + 0.1140 * B).
For my purposes (display to normal and color-deficient people) it was sufficient to being able to switch back and forth between colorspiral and an equivalent grayscale, which I derived by using the average of R, G, and B, I=(R/3 + G/3 + B/3).
Unfortunately I have not come across a solution for printing. If I recall this was posted as a challenge in the puzzler too but there was never a solution.

I am working on a perceptual rainbow in Lab space. If and when I get to it I will share it.


Matteo replied on : 38 of 40

Hi again Steve, maybe I asked the wrong question. What I really mean is: is there an upper limit to the value of Chroma? Thank you.

Matteo replied on : 40 of 40

Hi Steve

Have you seen any function to create and display the 3D outline of CRT gamut in Lab coordinates? it would be interesting to be able to plot your

Lab = [L, a, b];

line (and any other created with this method) to test if it’s within the gamut.


and see if