在 MATLAB 中定义用于颜色条的向量

Define vector to use for colorbar in MATLAB

我正在绘制 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

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

在你的例子中,试试这个:第一个子图 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

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

这是结果:

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

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