【问题标题】:Color each section in a stacked bar plot differently以不同方式为堆积条形图中的每个部分着色
【发布时间】:2017-08-17 00:41:29
【问题描述】:

我在下面有一个堆积条形图:-

这是使用以下方法生成的:

b = barh(1:3,rand(3,2),'stacked');

现在我有一个 3x2 单元 C 每个单元元素是一个 1x3 RGB 数组。

C = cell(3,2);
for i = 1:3
  for j = 1:2
    C{i,j} = rand(1,3);
  end
end

图中有6个方框,对应6种颜色。我想在框中填充这些指定的颜色。我想用这个方法:

b(1).Parent.Parent.Colormap = C;

...但它不起作用。

有人可以建议如何通过控制每个条形段的颜色来绘制自定义堆叠条形图吗?我认为调整 MATALB 的 bar 命令不会有帮助。

【问题讨论】:

  • 如果您尝试单独为每个条形着色,也许bar 图表并不是您想要的。
  • 提示:打开plot-tools看看实际发生了什么,手动编辑一下,然后看看Matlab使用的代码[(在图窗口中,file>generate M-file)] .
  • 您使用的是哪个 MATLAB 版本?如果使用barh 完成,看起来需要对matlab.graphics.primitive.world.Quadrilateral 类进行一些逆向工程......
  • @Dev-iL 我正在使用 MATLAB 版本:9.2.0.556344 (R2017a)。你能指出一个这样做的来源吗?
  • 您可能还想看这里:stackoverflow.com/a/45571774/2627163

标签: matlab plot visualization data-visualization matlab-figure


【解决方案1】:

您需要复制和操作bar(或barh)函数返回的图形对象

bar(y, 'stacked')y 中的每一列返回一个条形图形对象。图形对象有XDataYData 字段,它们控制条形部分的位置和大小。由于同一列中的所有部分都共享图形对象,因此您不能单独操作颜色。

例如,如果y 是一个 2x3 矩阵,bar 返回 3 个图形对象。每个对象都有:

  • XData,一个包含条形索引的 1x2 向量
  • YData,一个 1x2 向量,每个元素都是该部分的高度。
  • FaceColor,所有这些部分共享的颜色

我的代码复制了这些图形对象,因此您有 6 个具有 1x1 XDataYDatafields 的图形对象,而不是 3 个具有 1x2 XDataYData 字段的图形对象,每个图形对象都有一个唯一的 @987654341 @。

从正常的 barbarh 图表开始

figure;
n_bars = 2;
n_sections = 3;

%Initialize the bar graph with default coloring
b = bar(rand(n_bars, n_sections), 'stacked');

现在,制作一个新图形来保存带有操纵颜色的绘图

%Make new figure with new color scheme
f = figure;
a = axes('Parent', f);

%Colors
C = rand(6, 3);

对于每个原始图形对象,制作两个副本。

for jj = 1:n_sections
  %Duplicate the bar graphics object results 
  section1 = copyobj(b(jj), a);
  section2 = copyobj(b(jj), a);

  % Remove one of the bars from each section
  section1.YData(1) = 0;
  section2.YData(2) = 0;

  %Change the color
  section1.FaceColor = C(sub2ind([n_bars, n_sections], 1, jj), :);
  section2.FaceColor = C(sub2ind([n_bars, n_sections], 2, jj), :);
end

之前和之后!

【讨论】:

  • jj 的范围为 1。
  • @user_1_1_1 哎呀,这是调试神器
【解决方案2】:

想法是为每个数据行创建一个单独的图表,否则我们无法获取单个条形对象句柄。

ydata = rand(3,2); cdata={'r','g'; 'b','y';'c','k';'g','b'};
numplots = size(ydata,1);
h=zeros(numplots,2);
figure, hold on
for k=1:numplots,
    h(k,:) = barh(nan(size(ydata)),'stacked');
    set(h(k,1),'FaceColor',cdata{k,1});
    set(h(k,2),'FaceColor',cdata{k,2});
    tmp_ydata = get(h(k,1),'YData');
    tmp_ydata(k) = ydata(k,1); 
    set(h(k,1),'YData',tmp_ydata);
    tmp_ydata = get(h(k,2),'YData');
    tmp_ydata(k) = ydata(k,2);
    set(h(k,2),'YData',tmp_ydata);
end
hold off 

有关详细信息,请参阅帖子“突出显示图表的部分” Mike on MATLAB Graphics

【讨论】:

    【解决方案3】:

    根据塞西莉亚的回答,这里是一个更通用的解决方案。

    n_bars = 3;
    n_sections = 4;
    b = barh(rand(n_bars, n_sections), 'stacked');
    
    f = figure;
    a = axes('Parent', f);
    C = rand(n_bars*n_sections, 3);
    for jj = 1:n_sections
        for ii=1:n_bars
            section=copyobj(b(jj), a);
            dummy=1:n_bars;
            dummy(dummy==ii)=[];
            section.YData(dummy) = 0;
            section.FaceColor = C(sub2ind([n_bars, n_sections], ii, jj), :);
        end
    end
    

    对于n_barsn_sections 的任何值,这将起作用。如果有人可以建议矢量化或更有效的实现,请这样做。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-30
      • 1970-01-01
      • 2021-12-02
      相关资源
      最近更新 更多