I was wondering how one plots something like this :
http://en.wikipedia.org/wiki/Image:CIExy1931.svg
The axis is in "bent" into that shape and each x axis value corresponds to
the wavelength of light, which in turn corresponds (roughly) to the colour
shown on the plot. Monochromatic colours form the locus of the plot (the
axis), while mixed colors define the interior.
I have searched on file exchange, and though there are some hits that come
close (mainly relating to conversion of color spaces), there is really
nothing I could find.
Can anyone suggest how this plot may be plotted ? After plotting, I would
have to add contours / points to the plot to represent actual experimental
data.
Start by downloading the 1931 CIE color matching functions, x_bar, y_bar
and z_bar from
<http://www.cvrl.org/database/data/cmfs/ciexyz31_1.txt>
Next, compute x and y:
x = x_bar./(x_bar + y_bar + z_bar);
y = y_bar./(x_bar + y_bar + z_bar);
Then plot them:
plot(x,y)
That gets you the shape you want. To fill it with color, something like
what is shown on the web page, you need to make a patch:
% assume x_bar, etc. are column vectors.
n = length(x_bar);
rgb = reshape([x_bar,y_bar,z_bar],[n 1 3]);
p = patch(x,y,rgb);
The colors on that patch are about the correct hue, but most are too
dark. As I'm not sure exactly what you are trying to do I'll let you
figure out how to go from here.
--
Doug Schwarz
dmschwarz&ieee,org
Make obvious changes to get real email address.
Thanks for the quick turn around (and happy new year !).
I tried out what you suggested.
All I get is a closed dark line defining the shape (that is what the patch
command does after the initial plot command plots an open curve in blue).
The area inscribed by this shape is white/blank (needs to be colored
according to the CIE coordinates). Further, I need tick marks along the
shape, marking out the locus of monochromatic emissions.
I am trying to plot out CIE values (as isolated points) calculated from the
spectra of a bunch of LEDs onto a colored CIE plot like the one in the URL.
I will try to take it from here, but was wondering if you had any further
pointers.
I am using the following table for the tristimulus values and x, y and z :
http://www.isc.tamu.edu/~astro/color/cie_xyz1964.html
The code you presented above has a bug : the reshape should be on x, y and
z, not the tristimulus values.
The hues are rather dark and it does not look like a CIE plot.
> Doug Schwarz wrote:
>
> > In article <flcde4$rrg$1...@aioe.org>,
> > Geico Caveman <spammers...@spam.invalid> wrote:
> >
> >> Hello
> >>
> >> I was wondering how one plots something like this :
> >>
> >> http://en.wikipedia.org/wiki/Image:CIExy1931.svg
[snip]
> > Start by downloading the 1931 CIE color matching functions, x_bar, y_bar
> > and z_bar from
> >
> > <http://www.cvrl.org/database/data/cmfs/ciexyz31_1.txt>
> >
> > Next, compute x and y:
> >
> > x = x_bar./(x_bar + y_bar + z_bar);
> > y = y_bar./(x_bar + y_bar + z_bar);
> >
> > Then plot them:
> >
> > plot(x,y)
> >
> >
> > That gets you the shape you want. To fill it with color, something like
> > what is shown on the web page, you need to make a patch:
> >
> > % assume x_bar, etc. are column vectors.
> > n = length(x_bar);
> > rgb = reshape([x_bar,y_bar,z_bar],[n 1 3]);
> > p = patch(x,y,rgb);
> >
> > The colors on that patch are about the correct hue, but most are too
> > dark. As I'm not sure exactly what you are trying to do I'll let you
> > figure out how to go from here.
> >
>
> I am using the following table for the tristimulus values and x, y and z :
>
> http://www.isc.tamu.edu/~astro/color/cie_xyz1964.html
>
> The code you presented above has a bug : the reshape should be on x, y and
> z, not the tristimulus values.
>
> The hues are rather dark and it does not look like a CIE plot.
I finally had a chance to work on this some more. Try this code:
% x_bar, etc are column vectors at wavelengths, wl.
x = x_bar./(x_bar + y_bar + z_bar);
y = y_bar./(x_bar + y_bar + z_bar);
wl = wl(:);
n = length(wl);
% blue blue cyan green yellow orange red red
wl0 = [360 470 492 520 575 600 630 830]'; % wavelengths in nm.
rgb0 = [0 0 1;0 0 1;0 1 1;0 1 0;1 1 0;1 0.5 0;1 0 0;1 0 0];
rgb = [pchip(wl0,rgb0(:,1),wl), pchip(wl0,rgb0(:,2),wl),...
pchip(wl0,rgb0(:,3),wl)];
for k = 1:n-1
rgb2 = permute([1 1 1;rgb(k,:);rgb(k+1,:)],[1 3 2]);
patch([1/3;x(k:k+1)],[1/3;y(k:k+1)],rgb2,'edgecolor','none');
end
rgb2 = permute([1 1 1;rgb(end,:);rgb(1,:)],[1 3 2]);
patch([1/3;x([end 1])],[1/3;y([end 1])],rgb2,'edgecolor','none');
patch(x,y,'-k','facecolor','none','edgecolor','k')
hold on
plot(1/3,1/3,'ok')
hold off
axis equal
axis([0 .8 0 .9])
This code can be vectorized -- I just didn't bother. The appearance
isn't identical to the plot from wikipedia, but it's close. You can
play with the reference wavelengths, wl0, if you think you might be able
to do better.
Basically, instead of a single polygon, we now have a series of small
wedges with the color of the common center point being white.
I didn't plot the wavelengths around the arc, but you should be able to
handle that.
Interesting problem.
[WL, xFcn, yFcn, zFcn] = colorMatchFcn('CIE_1931');
v=[0:.001:1];
[x,y]=meshgrid(v,v); y=flipud(y);
z=(1-x-y);
rgb=applycform(cat(3,x,y,z),makecform('xyz2srgb'));
ciex=xFcn./sum([xFcn; yFcn; zFcn],1);
ciey=yFcn./sum([xFcn; yFcn; zFcn]);
nciex=ciex*size(rgb,2);
nciey=size(rgb,1)-ciey*size(rgb,1);
%mask=~any(rgb==0,3); mask=cat(3,mask,mask,mask);
mask=roipoly(rgb,nciex,nciey); mask=cat(3,mask,mask,mask);
figure; imshow(rgb.*mask+~mask); hold on;
[C,IA,IB]=intersect(WL,[400 460 470 480 490 520 540 560 580 600 620 700]);
text(nciex(IA),nciey(IA),num2str(WL(IA).'));
axis on;
set(gca,'XTickLabel',get(gca,'XTick')/(size(rgb,2)-1));
set(gca,'YTickLabel',1-get(gca,'YTick')/(size(rgb,1)-1));
title('CIE Chromaticity'); xlabel('x'); ylabel('y');
Hello Jonathan,
I am trying to plot the CIE 1976 Lu'v' chromaticity diagram. I've tried adapting your code to it but it did not work. I am having trouble creating the L, u' and v' mesh grids. While with the XYZ coordinates the Z is dependent on the X and Y, with the Lu'v' coordinates I cannot find such dependancy which I could implement in the code. Do you have any suggestions?
I thank you in advance, Adi.