Я делаю некоторый анализ и мне нужно создать график гистограммы. Я знаю, как создать стандартный график гистограммы, но мне нужно что-то вроде изображения ниже, где каждая точка представляет собой интервал по оси x. Например, каждый бин основан на значении из x-x.
@SecretAgentMan, хорошо, мой флаг убран, так как другой ответ не рекомендуется. Затем можно добавить новый ответ с использованием histc
здесь или в другом посте.
я не уверен, какой ответ вы оба имеете в виду
@rinkert, согласен, я думаю, что ответ заключается в использовании histogram
и настройке свойства гистограммы, но сейчас нет времени, чтобы дать полный качественный ответ.
Связанный пост (но не дубликат) здесь, но в этом ответе используется функция, которая больше не рекомендуется Matlab.
Что плохого в том, чтобы просто использовать аргумент «BinWidth» и установить интервал на желаемый интервал? Для ячеек «больше чем» для гистограмм в Mathworks есть простое решение связь.
Вы можете использовать функцию histogram
, а затем установить позиции XTick
и XTickLabels
соответственно. См. комментарии в коде для объяснения.
% random normally distrubuted data
x = 1*randn(1000,1);
edges = -5:1:5;
% create vector with labels (for XTickLabel ... to ...)
labels = [edges(1:end-1); edges(2:end)];
labels = labels(:);
% plot the histogram
figure();
ax = axes;
h = histogram(x, 'BinEdges', edges, 'Normalization', 'Probability');
ax.XTick = edges + mean(diff(edges)/2);
ax.XTickLabel = sprintf('%.1f to %.1f\n', labels);
ax.XTickLabelRotation = 90;
% set yticks to percentage
ax.YTickLabel = cellfun(@(a) sprintf('%i%%', (str2double(a)*100)), ax.YTickLabel, 'UniformOutput', false);
% text above bars
bin_props = h.BinCounts/numel(x); % determine probabilities per bin in axis units
bin_centers = ax.XTick(1:end-1); % get the bin centers
txt_heigts = bin_props + 0.01; % put the text slightly above the bar
txt_labels = split(sprintf('%.1f%% ', bin_props*100), ' ');
txt_labels(end) = []; % remove last cell, is empty because of split.
text(ax, bin_centers, txt_heigts, txt_labels, 'HorizontalAlignment', 'center')
% set ylim to fit all text (otherwise text is outside axes)
ylim([0 .4]);
Для размещения текста в нужном месте может потребоваться некоторая настройка. Наиболее важным является параметр 'HorizontalAlignment'
и расстояние до стержней. Я также использовал опцию 'Normalization'
, 'probability'
из функции histogram
и установил ось Y, чтобы также отображать проценты.
Я полагаю, что вы можете сделать дополнение ниже самостоятельно, когда это необходимо.
Когда ваши данные могут быть за пределами определенного binedges
, вы можете обрезать свои данные и установить XTickLabels
со знаками меньше или больше.
% when data can be outside of defined edges
x = 5*randn(1000,1);
xclip = x;
xclip(x >= max(edges)) = max(edges);
xclip(x <= min(edges)) = min(edges);
% plot the histogram
figure();
ax = axes;
h = histogram(xclip, 'BinEdges', edges);
ax.XTick = edges + mean(diff(edges)/2);
ax.XTickLabel = sprintf('%.1f to %.1f\n', labels);
ax.XTickLabelRotation = 90;
% set boundary labels
ax.XTickLabel{1} = sprintf('\\leq %.1f', edges(2));
ax.XTickLabel{end-1} = sprintf('\\geq %.1f', edges(end-1));
Вы также можете установить внешние края на -Inf
и Inf
, как указал пользователь 2305193. Так как внешние бины тогда намного шире (потому что они фактически простираются до Inf
по оси x), что вы можете исправить, установив ось xlim
. По умолчанию XTickLabels
будет отображать -Inf to -5.0
, что лично мне не нравится, поэтому я установил для них знаки меньше (и равно) и больше.
step = 1;
edges = -5:step:5; % your defined range
edges_inf = [-Inf edges Inf]; % for histogram
edges_ext = [edges(1)-step edges]; % for the xticks
x = 5*randn(1000,1);
% plot the histogram
figure();
ax = axes;
h = histogram(x, 'BinEdges', edges_inf, 'Normalization', 'probability');
labels = [edges_inf(1:end-1); edges_inf(2:end)];
labels = labels(:);
ax.XTick = edges_ext + step/2;
ax.XTickLabel = sprintf('%.1f to %.1f\n', labels);
ax.XTickLabelRotation = 90;
% show all bins with equal width (Inf bins are in fact wider)
xlim([min(edges)-step max(edges)+step])
% set boundary labels
ax.XTickLabel{1} = sprintf('\\leq %.1f', edges(1));
ax.XTickLabel{end-1} = sprintf('\\geq %.1f', edges(end));
Блин это именно то, что мне было нужно. Есть ли способ показать процент, как на исходном рисунке, который я прикрепил. Я знаю, как нормализовать ось через нормализацию - вероятность.
@VBA_Novice, посмотрите на свойство normalization
. Выберите свой метод нормализации и используйте это свойство при вызове функции histogram
.
Отличный ответ. Отвечает на вопрос ОП и ясно для будущих посетителей. (+1)
@Hoki, я знаю, как нормализовать при вызове функции гистограммы. Что я спрашивал: можно ли как-то показать процент поверх каждой корзины, как показано на моем изображении, которое я разместил.
я согласен, что это отличный ответ. Мне это помогло. спасибо @ринкерт
@rinkert, согласен с обманом, но в этом ответе не используется
histogram
, который теперь рекомендуется вместоhistc
, используемого в этом ответе.