Octave 一张图中的多个条形图

Multiple bar charts in one graph in Octave

在 Windows 上使用 Octave 4.2.1 和 qt 图形工具包(我不能使用 gnuplot,因为它在代码的其他部分崩溃了)。我有一个 35x7x4 的数据集(4 个通道上 7 个条件下的 35 个数据点)——您可以使用随机数据来完成本练习。

我正在尝试创建 4 个子图(每个通道 1 个),每个子图上有 7 个条形图(每个条件一个),以查看数据分布如何随每个条件变化。每个 7x4 = 28 分布都有自己的一组 bin 和频率,我似乎无法将 7 个数据集组合在一个图(子图)上。

发布整个代码会太复杂,但这里有一个简化版本:

nb_channels = 4;
nb_conditions = 7;
nbins = 15;
freq = zeros(nbins,nb_conditions,nb_channels);
xbin = zeros(nbins,nb_conditions,nb_channels);

plot_colours = [91 237 165 255 68 112 255;
  155 125 165 192 114 173 0;
  213 49 165 0 196 71 255];
plot_colours = plot_colours / 255;

for k = 1:nb_channels
  for n = 1:nb_conditions
    % some complex calculations to generate temp variable
    [freq(:,n,k),xbin(:,n,k)] = hist(temp,nbins);
  end
end

figure
for k = 1:nb_channels
  subplot(2,2,k)
  for n = 1:nb_conditions
    bar(xbin(:,n,k),freq(:,n,k),'FaceColor',plot_colours(:,n))
    hold on
  end
  hold off
  legend('condition #1','condition #2','condition #3','condition #4','condition #5','condition #6','condition #7')
end

它给出了这样的东西:

所以你真的看不到任何东西,所有的条都在彼此的顶部。此外,Octave 不支持补丁对象的透明度 属性(这是条形图使用的),所以我不能将直方图叠加在彼此之上,我真的很想这样做。

有没有更好的方法来解决这个问题?似乎 bar 只接受 x 数据的向量而不是矩阵,所以我不得不使用 hold on 并循环遍历各种条件,而不是使用矩阵方法。

好的,我会根据评论中的建议尝试回答我自己的问题:

建议 1:让所有垃圾箱都一样

这确实在一定程度上改善了结果,但由于补丁对象缺乏透明度,这仍然是一个问题。

代码更改:

nbins = 15;
xbin = linspace(5.8,6.5,nbins);

for k = 1:nb_channels
  for n = 1:nb_conditions
    % some complex calculations to generate temp variable
    freq_flow(:,n,k) = hist(temp,xbin);
  end
end

figure
for k = 1:nb_channels
  subplot(2,2,k)
  for n = 1:nb_conditions
    bar(xbin,freq_flow(:,n,k),'FaceColor',plot_colours(:,n))
    hold on
  end
  hold off
  xlim([5.8 6.3])
  legend('condition #1','condition #2','condition #3','condition #4','condition #5','condition #6','condition #7')
end

给出以下情节:

建议 2:使用折线图而不是条形图

这有助于提高可读性。不过结果有点"piece-wise".

代码更改:

 figure
    for k = 1:nb_channels
      subplot(2,2,k)
      for n = 1:nb_conditions
        plot(xbin,freq_flow(:,n,k),'LineStyle','none','marker','.',...
            'markersize',12,'MarkerEdgeColor',plot_colours(:,n),...
            'MarkerFaceColor',plot_colours(:,n))
        hold on
      end
      hold off
      xlim([5.8 6.3])
      legend('condition #1','condition #2','condition #3','condition #4','condition #5','condition #6','condition #7')
    end

结果如下:

图例有点乱,但我可能会解决这个问题。

我也尝试过的一个变体是只绘制点作为标记,然后在顶部绘制一个拟合正态分布。我不会 post 这里的所有代码,但结果看起来像这样:

建议 3:使用 gnuplot 解决透明度问题

不幸的是,在我开始使用透明度解决方法之前,gnuplot 在尝试绘制图形时一直崩溃。我认为它不喜欢子图和图例(这就是我首先转向 qt 图形工具包的原因,因为我在代码的其他部分遇到了完全相同的问题)。

解决方案 4:使用 3D 条形图

我在 SO 上找到了这个:3D histogram with gnuplot or octave

并这样使用它:

figure
for k = 1:size(flow_factor,2)
  subplot(2,2,k)
  h = my_bar3(freq_flow(:,:,k));
  fvcd = kron((1:numel(freq_flow(:,:,k)))', ones(6,1));
  set(h, 'FaceVertexCData',fvcd, 'FaceColor','flat', 'CDataMapping','scaled')
  colormap hsv; axis tight; view(50,25)
  ylbl = cell(length(xbin),1);
  for k=1:length(xbin)
    ylb{k} = num2str(xbin(k));
  end
  set(gca,'YTick',1:2:nbins);
  set(gca,'YTickLabel',ylb(1:2:end));
end

生产:

还不错,但可能不如线图清晰。

结论

总的来说,我可能最终会使用其中一种线图方法,因为它们往往更清晰。