MATLAB:如何组合和归一化不同样本大小的直方图

5

我有四组数据,我想在MATLAB中用一张图表示它们的分布。目前的代码如下:

[n1,x1]=hist([dataset1{:}]);
[n2,x2]=hist([dataset2{:}]);
[n3,x3]=hist([dataset3{:}]);
[n4,x4]=hist([dataset4{:}]);
bar(x1,n1,'hist'); 
hold on; h1=bar(x1,n1,'hist'); set(h1,'facecolor','g')
hold on; h2=bar(x2,n2,'hist'); set(h2,'facecolor','g')
hold on; h3=bar(x3,n3,'hist'); set(h3,'facecolor','g')
hold on; h4=bar(x4,n4,'hist'); set(h4,'facecolor','g')
hold off 

我的问题是每组采样大小都不同,数据集1的n为69,数据集2的n为23,数据集3和数据集4的n分别为10。那么,在将这三个组合在一起时,如何规范化分布呢?有没有什么方法可以例如通过该组的采样将每个箱中的实例除以采样来进行呢?

为什么不使用 n1/sum(n1) 来代替 bar?否则,histogram(x,'Normalization','probability') 可以作为另一种选择。 - Florian
n1/sum(n1)的效果很好,有没有办法用histfit来实现这个功能?或者有更好/更简单的方法来添加拟合线吗? - user3470496
1个回答

2

您可以通过将元素总数除以直方图中的每个元素来将其归一化:

[n1,x1] = histcounts(randn(69,1));
[n2,x2] = histcounts(randn(23,1));
[n3,x3] = histcounts(randn(10,1));
[n4,x4] = histcounts(randn(10,1));
hold on
bar(x4(1:end-1),n4./sum(n4),'histc');
bar(x3(1:end-1),n3./sum(n3),'histc');
bar(x2(1:end-1),n2./sum(n2),'histc');
bar(x1(1:end-1),n1./sum(n1),'histc');
hold off 
ax = gca;
set(ax.Children,{'FaceColor'},mat2cell(lines(4),ones(4,1),3))
set(ax.Children,{'FaceAlpha'},repmat({0.7},4,1))

然而,正如您在上面看到的那样,您可以做一些事情使您的代码更简单和短:
  1. 您只需要执行hold on一次。
  2. 使用axes句柄代替收集所有的bar句柄。
  3. 按数据集中元素数量的升序绘制条形图,以便所有直方图都清晰可见。
  4. 使用axes句柄设置所有属性。
顺便说一句 - 最好使用histcounts。这是结果:

only hist


编辑:

如果您想同时绘制来自histfit的pdf线,则可以先保存它,然后绘制标准化的线:

dataset = {randn(69,1),randn(23,1),randn(10,1),randn(10,1)};
fits = zeros(100,2,numel(dataset));
hold on
for k = numel(dataset):-1:1
    total = numel(dataset{k}); % for normalizing
    f = histfit(dataset{k}); % draw the histogram and fit
    % collect the curve data and normalize it:
    fits(:,:,k) = [f(2).XData; f(2).YData./total].';
    x = f(1).XData; % collect the bar positions
    n = f(1).YData; % collect the bar counts
    f.delete % delete the histogram and the fit
    bar(x,n./total,'histc'); % plot the bar
end
ax = gca; % get the axis handle
% set all color and transparency for the bars:
set(ax.Children,{'FaceColor'},mat2cell(lines(4),ones(4,1),3))
set(ax.Children,{'FaceAlpha'},repmat({0.7},4,1))
% plot all the curves:
plot(squeeze(fits(:,1,:)),squeeze(fits(:,2,:)),'LineWidth',3)
hold off

还有一些其他的改进可以引入到你的代码中:

  1. 将所有内容放入循环中,以便以后更容易进行更改。
  2. 将所有曲线数据收集到一个变量中,这样您就可以非常容易地将它们全部绘制在一起。

新的结果是:

hist & fit


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接