# How to draw a L*a*b* colour space or HSV colour space (2D)?

35 views (last 30 days)

Show older comments

Hi

I would like to draw the LAB or HSV colour space in 2D (see below) but I don't know how to draw it.

I found some code online (see below) which do something very similar (see the graph below) but NOT the same. The main difference is the colour at the center, it should be white, and the colours should graduately getting more and more saturated instead of one same colour from center all the way to the edge. What do I need to do in order to obtain a plot like the first graph??

r = linspace(0,1,10);

theta = linspace(0, 2*pi, 100);

[rg, thg] = meshgrid(r,theta);

[x,y] = pol2cart(thg,rg);

pcolor(x,y,thg);

colormap(hsv);

shading flat;

axis equal;

##### 1 Comment

Guillaume
on 6 Mar 2019

### Accepted Answer

Guillaume
on 6 Mar 2019

As commented in your question, note that you're only plotting one slice of the 3D colour space.

Of course, your original code doesn't work, you end up doing

pcolor(x, y, thg);

so you're only plotting the hue (angle) against x and y. There's no saturation or value information in your plot. You then apply a colour map called hsv whose colours are derived from the hsv cylinder, but in no way does it mean you've done any conversion to/from hsv. The whole idea is flawed.

Here is how I'd do it:

%inputs:

%plotradius: the plot radius of the disk. Image will be 2*plotradius+1 x 2*plotradius+1

%plotvalue: the Value at which the slice of the HSV cylinder is to be taken. In the range 0-1

plotradius = 100;

plotvalue = 1;

[x, y] = meshgrid(-plotradius:plotradius); %get x,y coordinates of pixels in image

[hue, saturation] = cart2pol(x, y); %convert to angle, radius. Angle is the hue, radius is the saturation in the HSV cylinder

hue = (hue + pi) / (2*pi); %rescale from -pi:pi to 0:1 since matlab use 0:1 for the range of the hue

saturation = saturation / plotradius; %rescale saturation to range 0:1. Not that anything above 1 is outside the cylinder

value = ones(size(hue)) * plotvalue; %set value constant for all points in the disk

%now set points outside the disk (saturation >1) to white. That'd be a value of 1 and saturation of 0. hue doesn't matter

outsidedisk = saturation > 1;

saturation(outsidedisk) = 0;

value(outsidedisk) = 1;

%finally, convert hsv to rgb and plot

rgb = hsv2rgb(cat(3, hue, saturation, value));

imshow(rgb);

##### 2 Comments

Guillaume
on 6 Mar 2019

Matlab always draw the axis at the border of the image. If you want that:

imshow(rgb, 'XData', [-plotradius, plotradius], 'YData', [-plotradius, plotradius]);

axis on;

You can fake axes in the middle by drawing lines yourselves:

imshow(rgb, 'XData', [-plotradius, plotradius], 'YData', [-plotradius, plotradius]);

ax = gca;

ax.YDir = 'normal';

hold on;

plot(ax.XLim, [0, 0], 'k');

plot([0, 0], ax.YLim, 'k');

plot([ax.XTick; ax.XTick], repmat([-plotradius; plotradius] * ax.TickLength(1) * 3, 1, numel(ax.XTick)), 'k');

plot(repmat([-plotradius; plotradius] * ax.TickLength(1) * 3, 1, numel(ax.YTick)), [ax.YTick; ax.YTick], 'k');

text(ax.XTick, zeros(size(ax.XTick)) + plotradius*ax.TickLength(1)*10, ax.XTickLabel);

text(zeros(size(ax.YTick)) + plotradius * ax.TickLength(1) * 5, ax.YTick, ax.YTickLabel);

hold off;

### More Answers (3)

darova
on 6 Mar 2019

clc, clear, cla

m = 100;

n = 10;

r = linspace(0,1,n);

theta = linspace(0, 2*pi, m);

[rg, thg] = meshgrid(r,theta);

[x,y] = pol2cart(thg,rg);

a = hsv(m);

hold on

whitebg('k')

for i = 1:m

for j = 1:n

color = [1 1 1] - (1-a(i,:))*j/n;

plot(x(i,j), y(i,j),'color',color,'marker','.');

end

end

hold off

DGM
on 10 May 2022

One thing that should be pointed out is that when plotting these things in a rectangular image, some consideration should be given to the geometry of what's being shown. The results are otherwise misleading.

When plotting slices of the cylindrical representation of HSV/HSL, it makes sense to omit points outside of the circular S=1 boundary (like @Guillaume's answer does). Points outside that boundary are just truncated.

The same applies for any other color model, but the boundary of interest may not be intuitively obvious beforehand. Consider the extent of sRGB in LAB:

That's not a cylinder or a grid-aligned rectangular prism. Showing it as a set of full rectangular color fields misrepresents its extents. To add confusion, the appearance of out-of-gamut color points is determined by the rendering intent of the conversion tools, which is something that a viewer won't have any way of knowing.

Consider the example:

sz = [300 300]; % size of each slice image

nslices = 25;

% set up base LAB image

A = linspace(-110,110,sz(1));

B = linspace(-110,110,sz(2));

[A B] = meshgrid(A,B);

l = linspace(1,99,nslices);

outpict = cell(nslices,1);

for k = 1:nslices

% construct this slice

thisl = l(k)*ones(sz);

thisrgb = lab2rgb(cat(3,thisl,A,B));

% mark out-of-gamut regions

isoog = any(thisrgb>1,3) | any(thisrgb<0,3);

thisrgb(repmat(isoog,[1 1 3])) = 0;

% flip so that coordinates are correct

thisrgb = flipud(thisrgb);

% add a text label directly to the image

% textim() is part of MIMT (see File Exchange)

lbl = textim(sprintf('L = %d',round(l(k))),'ibm-iso-16x9');

thisrgb(10:size(lbl,1)+9,10:size(lbl,2)+9,:) = repmat(lbl,[1 1 3]);

outpict{k} = thisrgb;

end

% show all slices

montage(outpict)

The above example shows only the in-gamut regions for each slice. Right-click and view the image for more detail.

What if you want to draw a border around the in-gamut regions? In the HSV example, that might seem simple; just overlay a circle. It's not a simple in LAB. See this answer for an example:

Where did that spinning 3D plot come from?

csview('lab','invert')

th = linspace(0,360,25);

outpict = cell(numel(th)-1,1);

for f = 1:numel(th)-1

view(th(f),20)

outpict{f} = iminv(frame2im(getframe(gcf)));

end

outpict = imstacker(outpict,'padding',0);

gifwrite(outpict,'spinlab.gif',0.2);

The functions csview(), iminv(), imstacker(), gifwrite() and textim() are from MIMT on the File Exchange.

Csview() can either be used as a command-line tool like shown, or it can be launched with a GUI for interactive visualization of different color models.

##### 0 Comments

### See Also

### Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!