根据直方图的值范围创建分箱
create bins based on a range of values for histogram figure
我正在做一些分析,需要生成直方图。我知道如何创建标准直方图,但我需要类似下图的东西,其中每个点都是 x 轴上的一个间隔。例如,每个 bin 基于 x-x 中的一个值。
您可以使用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'
选项,以及到柱的距离。我还使用了 histogram
函数中的 'Normalization'
、'probability'
选项,并将 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
,正如 user2305193 指出的那样。由于外部 bin 更宽(因为它们实际上延伸到 x 轴上的 Inf
),您可以通过设置轴 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));
我正在做一些分析,需要生成直方图。我知道如何创建标准直方图,但我需要类似下图的东西,其中每个点都是 x 轴上的一个间隔。例如,每个 bin 基于 x-x 中的一个值。
您可以使用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'
选项,以及到柱的距离。我还使用了 histogram
函数中的 'Normalization'
、'probability'
选项,并将 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
,正如 user2305193 指出的那样。由于外部 bin 更宽(因为它们实际上延伸到 x 轴上的 Inf
),您可以通过设置轴 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));