MATLAB: объединение и нормализация гистограмм с разными размерами выборки

У меня есть четыре набора данных, распределение которых я хотел бы представить в 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. Итак, как мне нормализовать распределения при представлении этих трех групп вместе?

Есть ли способ... например... разделить экземпляры в каждой ячейке на выборку для этой группы?


person user3470496    schedule 14.02.2017    source источник
comment
Почему бы не запретить вместо этого n1/sum(n1)? В противном случае, возможно, histogram(x,'Normalization','probability') был бы альтернативой.   -  person Florian    schedule 14.02.2017
comment
n1/sum(n1) отлично сработало, есть ли способ сделать это с помощью histfit? или какой-то лучший/более простой способ добавить подходящие линии?   -  person user3470496    schedule 14.02.2017


Ответы (1)


Вы можете нормализовать гистограммы, разделив их на общее количество элементов:

[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. Вместо того, чтобы собирать все дескрипторы bar, используйте дескриптор axes.
  3. Постройте столбец в порядке возрастания количества элементов в наборе данных, чтобы все гистограммы были хорошо видны.
  4. С дескриптором axes установите все свойства одной командой.

и в качестве примечания - лучше использовать histcounts.

Вот результат:

только история


ИЗМЕНИТЬ:

Если вы хотите также построить линию PDF из histfit, вы можете сначала сохранить ее, а затем нормализовать:

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. Соберите все данные кривых в одну переменную, чтобы вы могли очень легко построить их все вместе.

Новый результат:

История и соответствие

person EBH    schedule 14.02.2017