MATLAB: How to add a color-dependent legend to scatter3 plot

examplehistogramhow tolegendMATLABMATLAB and Simulink Student Suitescatter3

I have a 3D histogram via scatter3, but I wish to add a legend to state the frequency signified by the color. How do I do this?
Also, I would appreciate any simplifications you could suggest to my code below.
%%Plot a scatter3 histogram of the shifts.
xdata = tumorshifts(:,1); ydata = tumorshifts(:,2);
zdata = tumorshifts(:,3);
size = 10*shiftno;
for loop = 1:length(size)
if isequal(shiftno(loop),1)
size(loop) = size(loop)/10;
end
end
color = zeros(length(shiftno),3);
values = unique(shiftno);
% Resource: http://www.wolframalpha.com/input/?i=orange+RGB
% http://www.wolframalpha.com/input/?i=576+nm+light+to+RGB
for loop = 1:length(color)
if shiftno(loop) == values(1)
color(loop,1) = 130; color(loop,2) = 130; color(loop,3) = 130; % grey
elseif shiftno(loop) == values(2)
color(loop,1) = 41; color(loop,2) = 0; color(loop,3) = 255; % 452 nm
elseif shiftno(loop) == values(3)
color(loop,1) = 0; color(loop,2) = 214; color(loop,3) = 69; % 514 nm
elseif shiftno(loop) == values(4)
color(loop,1) = 132; color(loop,2) = 252; color(loop,3) = 0; % 576 nm
elseif shiftno(loop) == values(5)
color(loop,1) = 255; color(loop,2) = 8; color(loop,3) = 0; % 638 nm
elseif shiftno(loop) == values(6)
color(loop,1) = 158; color(loop,2) = 0; color(loop,3) = 0; % crimson
end
end
scatter3(xdata,ydata,zdata,size,color/255)
axis equal
title(['Histogram of ',num2str(length(unique(elektapatients.StudyID))),...
' Elekta Patients'' Daily Shifts'])
xlabel('Left [mm]')
ylabel('Superior [mm]')
zlabel('Posterior [mm]')

Best Answer

%%Plot a scatter3 histogram of the shifts.
xdata = tumorshifts(:,1); ydata = tumorshifts(:,2);
zdata = tumorshifts(:,3);
pointsize = 10*shiftno;
for loop = 1:length(pointsize)
if shiftno(loop) == 1
pointsize(loop) = pointsize(loop)/10;
end
end
color = zeros(length(shiftno),3);
values = unique(shiftno);
% Resource: http://www.wolframalpha.com/input/?i=orange+RGB
% http://www.wolframalpha.com/input/?i=576+nm+light+to+RGB
cmap = [130, 130, 130; %grey
41, 0, 255; %452 nm
0, 214, 69; %514 nm
132, 252, 0; %576 nm
255, 8, 0; %638 nm
158, 0, 0]; %crimson
for loop = 1:length(color)
switch shiftno(loop)
case values(1): color(loop, :) = cmap(1,:); % grey
case values(2): color(loop, :) = cmap(2,:); % 452 nm
case values(3): color(loop, :) = cmap(3,:); % 514 nm
case values(4): color(loop, :) = cmap(4,:); % 576 nm
case values(5): color(loop, :) = cmap(5,:); % 638 nm
case values(6): color(loop, :) = cmap(6,:); % crimson
end
end
scatter3(xdata, ydata, zdata, pointsize, color/255)
axis equal
title(['Histogram of ', num2str(length(unique(elektapatients.StudyID))),...
' Elekta Patients'' Daily Shifts'])
xlabel('Left [mm]')
ylabel('Superior [mm]')
zlabel('Posterior [mm]')
hold on
for K = 1 : size(cmap, 1)
H(K) = scatter3(nan, nan, nan, K*10, cmap(K,:));
end
legend(H, {'grey', '452 nm', '514 nm', '576 nm', '638 nm', 'crimson'});
Note that size had to be renamed because you need the MATLAB size() function later.
Going from if/elseif to switch/case was just for cleaner code.
You might want to adjust the point size for the legend purposes.
Notice the trick here of using nan to create scatter points that will not show up. The points will exist and will have the proper color but they will not be rendered. This is done in order to get the individual handles of those scatter plots so that they can have individual legends generated. Any one scatter3() plot results in a single graphics handle and that would only permit a single legend entry. You need to create different handles for each entry you want to make.
Related Question