84 views (last 30 days)

Show older comments

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

Nick Counts
on 9 Nov 2016

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! :)

Nick Counts
on 8 Nov 2016

Edited: Nick Counts
on 8 Nov 2016

Joel,

I don't know about a vector, but you can set upper and lower limits. It looks like you are saving a handle to the colorbar in variable 'c'

Try:

c.Limits = [0 10]

Obviously use whatever numbers make sense for your plots :)

Good luck!

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

Start Hunting!