MATLAB: Define vector to use for colorbar

colorbar; colormap; scatter plot; bar plotMATLAB

Hi,
I am plotting a bar+scatter plot where the scatter points are colored according to a separate variable. The problem I am having is that the colorbar is, for some reason that is beyond me, using the wrong values at the moment. If I just plot the scatter plot and add a colorbar, then the range of the colorbar is correct. I have been trying every solution I can come up with, but have not made any progress. Any help would be very much appreciated. Please find a working example of the code below;
figure
subplot(2,1,1)
a = 1;
b = 2;
r = (b-a).*rand(1,7) + a;
y = r;
rr = (b-a).*rand(1,7) + a;
z = rr;
x = [1:7];
zz = rand(1,7)
yyaxis left
hold on
for i = 1:7
h=bar(i,y(i), 'FaceColor',[1 1 1], 'LineWidth',3);
yb(i) = cat(1, h.YData);
xb(i) = bsxfun(@plus, h(1).XData, [h.XOffset]');
if zz(i) < 0.0300000
set(h,'EdgeColor','k');
elseif zz(i) < 0.050000000
set(h,'EdgeColor','b');
elseif zz(i) < 0.070000000
set(h,'EdgeColor','g');
else
set(h,'EdgeColor','r');
end
end
ylabel('hm', 'FontSize', 12, 'FontWeight', 'bold')
for i1=1:7
t = text(xb(i1)-0.2,yb(i1),num2str(yb(i1),'%0.3f'),...
'HorizontalAlignment','center',...
'VerticalAlignment','bottom')
s = t.FontSize;
t.FontSize = 12;
t.FontWeight = 'bold';
end
yyaxis right
pointsize = 40;
hh = scatter(x,z,pointsize, zz,'filled')
cc = colormap([hsv(20)])
c = colorbar
c.Label.String = 'Pos';
set(gca,'Ydir','reverse')
ylabel('OK', 'FontSize', 12, 'FontWeight', 'bold')
lgd = legend([h, hh], 'hm', 'OK')
subplot(2,1,2)
x = [1:8]
a = 1;
b = 2;
r = (b-a).*rand(1,8) + a;
y = r;
rr = (b-a).*rand(1,8) + a;
z = rr;
zz = rand(1,8);
yyaxis left
hold on
for i = 1:8
h=bar(i,y(i), 'FaceColor',[1 1 1], 'LineWidth',3);
yb(i) = cat(1, h.YData);
xb(i) = bsxfun(@plus, h(1).XData, [h.XOffset]');
if zz(i) < 0.0300000
set(h,'EdgeColor','k');
elseif zz(i) < 0.050000000
set(h,'EdgeColor','b');
elseif zz(i) < 0.070000000
set(h,'EdgeColor','g');
else
set(h,'EdgeColor','r');
end
end
for i1=1:8
t = text(xb(i1)-0.2,yb(i1),num2str(yb(i1),'%0.3f'),...
'HorizontalAlignment','center',...
'VerticalAlignment','bottom')
s = t.FontSize;
t.FontSize = 12;
t.FontWeight = 'bold';
end
ylabel('hm', 'FontSize', 12, 'FontWeight', 'bold')
yyaxis right
pointsize = 40;
hh = scatter(x,z,pointsize, zz,'filled')
set(gca,'Ydir','reverse')
ylabel('OK', 'FontSize', 12, 'FontWeight', 'bold')
c = colorbar
c.Label.String = 'Pos';
lgd = legend([h, hh], 'hm', 'OK')
%title(lgd,'My Legend Title')
hold off
Thanks in anticipation.
Regards Joel

Best Answer

Ok, I spend some time with this and I think i see what's happening. It all boils down to the way you define the CData property of your scatter plot. Here is a simple example that should illustrate how it works:
xData = 1:10
yData = rand(1, 10) + 1 % random number between 1 and 2
cVect = yData;
colormap(jet(10));
hScat = scatter(xData, yData, 100, cVect, 'Filled')
hcbar = colorbar
caxis([1 2])
This sets the CData to the same value as the yData vector, and then we use caxis to determine the boundaries of the displayed color scale.
Now in your code, it looks like you are using the variable zz as your CData value in your scatter plot. You define it this way:
zz = rand(1,7)
This means it will be a 7 element vector with values between 0 and 1. When you use colormap you are creating an array of colors that your CData will be mapped to. Without specifying a caxis, I think Matlab automatically maps the bottom color to the lowest CData value, and the top color to the highest CData value.
From your code, I assume you want to map a zz value of 0 to the bottom color, and a zz value of 1 to the top color?
If so, the following simplification of your example should do the trick:
figure
% Generate Data
a = 1;
b = 2;
r = (b-a).*rand(1,7) + a;
y = r;
rr = (b-a).*rand(1,7) + a;
z = rr;
x = [1:7];
zz = rand(1,7)
% yyaxis left % Removed because I'm on 2014b
% Draw rectangles
hold on
for i = 1:7
hBarGraph = bar(i,y(i), 'FaceColor',[1 1 1], 'LineWidth',3);
yb(i) = cat(1, hBarGraph.YData);
xb(i) = bsxfun(@plus, hBarGraph(1).XData, [hBarGraph.XOffset]');
if zz(i) < 0.0300000
set(hBarGraph,'EdgeColor','k');
elseif zz(i) < 0.050000000
set(hBarGraph,'EdgeColor','b');
elseif zz(i) < 0.070000000
set(hBarGraph,'EdgeColor','g');
else
set(hBarGraph,'EdgeColor','r');
end
end
ylabel('hm', 'FontSize', 12, 'FontWeight', 'bold')
% Text labels for rectangles
for i1=1:7
t = text(xb(i1)-0.2,yb(i1),num2str(yb(i1),'%0.3f'),...
'HorizontalAlignment', 'center',...
'VerticalAlignment', 'bottom');
t.FontSize = 12;
t.FontWeight = 'bold';
end
% yyaxis right % Removed because I'm on 2014b
% Scatter Plot
pointsize = 40;
hAxes = gca;
colormap(hsv(20))
colorBounds = [0 1];
caxis(colorBounds)
colorbar
hScatterPlot = scatter(x,z,pointsize, zz,'filled')
set(hAxes,'Ydir','reverse')
ylabel('OK', 'FontSize', 12, 'FontWeight', 'bold')
lgd = legend([hBarGraph, hScatterPlot], 'hm', 'OK')
If this doesn't help, please let us know more about what color behavior you want. Good luck, and let us know how it goes! :)