对堆积条形图中的每个部分着色不同

时间:2017-08-17 00:41:29

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

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

enter image description here

这是使用:

生成的
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命令会有所帮助。

3 个答案:

答案 0 :(得分:2)

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

bar(y, 'stacked')y中的每一列返回一个Bar图形对象。图形对象具有XDataYData字段,用于控制条形区域的位置和大小。由于同一列中的所有部分共享图形对象,因此无法独立操作颜色。

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

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

我的代码复制了这些图形对象,因此不是3个具有1x2 XDataYData字段的图形对象,而是有6个图形对象,其中包含1x1 XDataYData字段,每个字段都有唯一的FaceColor

使用正常的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

之前和之后!

Default bar plot Modified bar plot

答案 1 :(得分:1)

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

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

答案 2 :(得分:1)

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

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的任何值,这都可行。如果有人可以建议矢量化或更有效的实施,请做。