在MATLAB中定义用于colorbar的向量

时间:2016-11-08 12:48:48

标签: matlab matlab-figure scatter-plot colorbar

我正在绘制一个bar + scatter图,其中散点根据单独的变量着色。我遇到的问题是colorbar目前正在使用错误的值。如果我只是绘制scatter图并添加colorbar,那么colorbar的范围就是正确的。

我正在使用Matlab 2016a。

请找到以下代码的工作示例:

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

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

修改 这个问题的一个解决方案的工作示例。

figure
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)
  colormap(jet)
  yyaxis left
  hold on
  for i = 1:length(y)
      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','k');
      elseif zz(i) < 0.070000000
          set(h,'EdgeColor','k');
      else
          set(h,'EdgeColor','k');
      end
  end
    cco = min(zz)
    cct = max(zz)
    caxis([cco cct])
    coloo = colorbar
    coloo.Label.String = 'Cbar';
    %h = bar(y, 0.2, 'FaceColor',[1 1 1], 'EdgeColor',[0 0 0],'LineWidth',2);
    %yb = cat(1, h.YData);
    %xb = bsxfun(@plus, h(1).XData, [h.XOffset]');
    for i1=1:7 % numel(yb)
        t = text(xb(i1)-0.3,yb(i1),num2str(yb(i1),'%0.3f'),...
                   'HorizontalAlignment','center',...
                   'VerticalAlignment','bottom')
                    s = t.FontSize;
                    t.FontSize = 12;
                    t.FontWeight = 'bold';
    end
    ylabel('OK', 'FontSize', 12, 'FontWeight', 'bold')
    yyaxis right
    pointsize = 80;
    hh = scatter(x,z,pointsize, zz,'filled')
    set(gca,'Ydir','reverse')
    ylabel('MM', 'FontSize', 12, 'FontWeight', 'bold')
    c = colorbar
    c.Label.String = 'Cbar';
    lgd = legend([h, hh], 'OK', 'MM')
    %title(lgd,'My Legend Title')
    hold off

1 个答案:

答案 0 :(得分:0)

问题在于zz。您可以将其定义为矢量,因此scatter使用图形颜色映射来选择与zz中的值相关的颜色。相反,将其定义为颜色矩阵,即n×3矩阵,其中每行定义RGB值介于0到1之间的一种颜色。

在您的示例中,请尝试以下操作:zz = rand(7,3)表示第一个子图,zz = rand(8,3)表示第二个子图。

这是您的代码,我使用颜色矩阵设置zz,并将其用于两个散点:

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;
%%%% this part is new: 
zz = [0    0.447 0.741;
    0.85  0.325 0.098;
    0.929 0.694 0.125;
    0.494 0.184 0.556;
    0.466 0.674 0.188;
    0.301 0.745 0.933;
    0.635 0.078 0.184;
    0.432 0.915 0.121];
%%%%%%%%%%%%%%%%%%%%%%%%
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(1:numel(x),:),'filled');
cc = colormap(hsv(20));
c = colorbar;
c.Label.String = 'Pos';
set(gca,'Ydir','reverse')
ylabel('OK', 'FontSize', 12, 'FontWeight', 'bold')
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;
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(1:numel(x),:),'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

还注意zz(1:numel(x),:)命令中的scatter,因此它将适应数据的大小。

这就是结果:

scatter+colorbar

编辑:在您的回复之后,我发现您希望颜色图中的颜色分散,但是仍然可以添加许多改进代码,所以我在这里发布了第二个版本几乎可以工作与您的第二次编辑完全一样,但更短更简单。了解这些技巧,他们会节省您的时间;)

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);
colormap(jet)
caxis([min(zz) max(zz)])
bary = diag(y);
bary(bary==0) = nan;
col_thresh = [0.03 0.05 0.07 1];
bar_color = {'r'; 'g'; 'b'; 'k'};
bar_group = sum(bsxfun(@lt,zz.',col_thresh),2);
yyaxis left
hold on
h = bar(bary,'stacked','FaceColor',[1 1 1], 'LineWidth',3);
set(h,{'EdgeColor'},bar_color(bar_group))
text(x-0.3,y,num2str(y.','%0.3f'),...
        'HorizontalAlignment','center',...
        'VerticalAlignment','bottom','FontSize',12,...
        'FontWeight','bold');
ylabel('OK', 'FontSize', 12, 'FontWeight', 'bold')
yyaxis right
pointsize = 80;
hh = scatter(x,z,pointsize,zz,'filled');
hh.Parent.YDir = 'reverse';
ylabel('MM', 'FontSize', 12, 'FontWeight', 'bold')
c = colorbar;
c.Label.String = 'Cbar';
legend([h(1), hh], 'OK', 'MM');
hold off

new_colorbar