Main Content

替换不建议使用的 hist 和 histc 实例

旧直方图函数(histhistc

MATLAB® 早期版本使用 histhistc 函数作为创建直方图和计算 bin 计数的主要方法。这些函数适用于某些常规用途,但总体能力有限。基于这些原因(及其他原因),不建议在新代码中使用 histhistc

  • 使用 hist 创建直方图后,修改该直方图的属性会有难度并要求重新计算整个直方图。

  • hist 的默认行为是使用 10 个 bin,这对很多数据集都不适用。

  • 绘制归一化直方图需要手动计算。

  • histhistc 的行为并不一致。

推荐的直方图函数

histogramhistcountsdiscretize 函数显著提高了 MATLAB 中创建和计算直方图的能力,同时提升了一致性和易用性。要为新代码创建和计算直方图,推荐使用 histogramhistcountsdiscretize 函数。

请特别注意以下更改,它们体现了相对于 histhistc改进

  • histogram 可以返回一个直方图对象。您可以使用该对象修改直方图的属性。

  • histogramhistcounts 都具有自动分 bin 和归一化功能,内置了几个常用选项。

  • histcountshistogram 的主要计算函数。这样各函数就具有一致的行为。

  • discretize 为确定每个元素的 bin 位置提供了其他选择和灵活性。

要求代码更新的差异

尽管做出了上述改进,但旧函数和当前建议的函数之间存在一些重要差异,这可能需要更新您的代码。下表汇总了这些函数之间的差异并提供了代码更新建议。

hist 的代码更新

差异使用 hist 时的旧行为使用 histogram 时的新行为

输入矩阵

hist 为输入矩阵的每一列创建直方图并在同一图窗中并排绘制直方图。

A = randn(100,2);
hist(A)

histogram 将整个输入矩阵视为一个高向量并创建一个直方图。要绘制多个直方图,请为每列数据创建一个不同的直方图对象。使用 hold on 命令在同一图窗中绘制直方图。

A = randn(100,2);
h1 = histogram(A(:,1),10)
edges = h1.BinEdges;
hold on
h2 = histogram(A(:,2),edges)

以上代码示例对每个直方图使用相同的 bin 边界,但在某些情况下,最好将每个直方图的 BinWidth 设置为相同。此外,出于显示目的,设置每个直方图的 FaceAlpha 属性可能会有所帮助,因为这会影响重叠条形的透明度。

Bin 设定

hist 接受 bin 中心作为另一个输入项。

histogram 接受 bin 边界作为另一个输入项。

要将 bin 中心转换为 bin 边界以用于 histogram,请参阅将 bin 中心转换为 bin 边

注意

若用于 hist 的 bin 中心是整数,例如 hist(A,-3:3),请使用 histogram 内置的用于整数的新分 bin 方法。

histogram(A,'BinLimits',[-3,3],'BinMethod','integers')

输出参量

hist 返回 bin 计数作为一个输出参量,也可以选择返回 bin 中心作为另一个输出参量。

A = randn(100,1);
[N, Centers] = hist(A)

histogram 返回一个直方图对象作为输出参量。该对象包含许多相关属性(bin 计数、bin 边界等)。可通过更改直方图的属性值修改它的各个方面。有关详细信息,请参阅 histogram

A = randn(100,1);
h = histogram(A);
N = h.Values
Edges = h.BinEdges

注意

要计算 bin 计数(而不绘制直方图),请将 [N, Centers] = hist(A) 替换为 [N,edges] = histcounts(A,nbins)

默认 bin 数量

默认情况下,hist 使用 10 个 bin。

默认情况下,histogramhistcounts 都使用自动分 bin 算法。bin 数量由输入数据的数量和范围程度确定。

A = randn(100,1);
histogram(A)
histcounts(A)

bin 范围

hist 使用最小和最大有限数据值来确定绘图中第一个和最后一个条形的左边缘与右边缘。-InfInf 分别包含在第一个和最后一个 bin 中。

如果未设置 BinLimits,则 histogram 会基于(但不完全等于)最小和最大的有限数据值来确定 bin 的有理数范围。histogram 将会忽略 Inf 值,除非其中一个 bin 边界将 Inf-Inf 显式指定为 bin 边界。

要重新生成 hist(A) 对有限数据(无 Inf 值)的结果,请使用 10 个 bin 并将 BinLimits 显式设置为最小和最大数据值。

A = randi(5,100,1);
histogram(A,10,'BinLimits',[min(A) max(A)])

histc 的代码更新

差异使用 histc 时的旧行为使用 histcounts 时的新行为
输入矩阵

histc 为输入数据的每列计算 bin 计数。对于 m×n 输入矩阵,histc 返回大小为 length(edges)×n 的 bin 计数矩阵。

A = randn(100,10);
edges = -4:4;
N = histc(A,edges)

histcounts 将整个输入矩阵视为一个高向量并计算整个矩阵的 bin 计数。

A = randn(100,10);
edges = -4:4;
N = histcounts(A,edges)

对每列使用 for 循环计算 bin 计数。

A = randn(100,10);
nbins = 10;
N = zeros(nbins, size(A,2));
for k = 1:size(A,2)
   N(:,k) = histcounts(A(:,k),nbins);
end

如果由于矩阵中的列数很多而造成性能问题,请考虑继续使用 histc 计算各列的 bin 计数。

最后一个 bin 中包含的值

如果 A(i) == edges(end)histc 会在最后一个 bin 中包含元素 A(i)。输出 N 是一个具有 length(edges) 个元素的向量,其中包含 bin 计数。落入 bin 范围外的值不会计算在内。

如果 edges(end-1) <= A(i) <= edges(end)histcounts 会在最后一个 bin 中包含元素 A(i)。换言之,histcounts 将来自 histc 的最后两个 bin 合并为最后一个 bin。输出 N 是一个具有 length(edges)-1 个元素的向量,其中包含 bin 计数。如果指定了 bin 边界,则落入 bin 外部的值不会计算在内。否则,histcounts 会自动确定要使用的适当 bin 边界以包含所有数据。

A = 1:4;
edges = [1 2 2.5 3]
N = histcounts(A)
N = histcounts(A,edges)

histc 中最后的 bin 主要用于整数计数。要使用 histcounts 执行这种整数计数,可以使用 'integers' bin 方法:

N = histcounts(A,'BinMethod','integers'); 
输出参量

histc 返回 bin 计数作为一个输出参量,也可以选择返回 bin 索引作为另一个输出参量。

A = randn(15,1);
edges = -4:4;
[N,Bin] = histc(A,edges)
  • 对于 N = histc(A,edges)[N,bin] = histc(A,edges) 之类的 bin 计数计算,请使用 histcountshistcounts 函数返回 bin 计数作为一个输出参量,也可以选择返回 bin 边界作为另一个输出参量,或返回 bin 索引作为第三个输出参量。

    A = randn(15,1);
    [N,Edges,Bin] = histcounts(A)
  • 对于 [~,Bin] = histc(A,edges) 之类的 bin 位置计算,请使用 discretizediscretize 函数提供用于确定每个元素的 bin 位置的其他选项。

    A = randn(15,1);
    edges = -4:4;
    Bin = discretize(A,edges)

将 bin 中心转换为 bin 边

hist 函数接受 bin 中心,而 histogram 函数接受 bin 边界。要更新代码以使用 histogram,您可能需要将 bin 中心转换为 bin 边界,以重现使用 hist 实现的结果。

例如,指定 bin 中心以用于 hist。这些 bin 具有均匀的宽度。

A = [-9 -6 -5 -2 0 1 3 3 4 7];
centers = [-7.5 -2.5 2.5 7.5];
hist(A,centers)

Figure contains an axes object. The axes object contains an object of type patch. This object represents A.

要将 bin 中心转换为 bin 边界,请计算 centers 中各连续值之间的中点。此方法会重现均匀和非均匀 bin 宽度对应的 hist 结果。

d = diff(centers)/2;
edges = [centers(1)-d(1), centers(1:end-1)+d, centers(end)+d(end)];

hist 函数包括落入每个 bin 右边界上的值(第一个 bin 包含两个边界),而 histogram 包括落入每个 bin 左边界上的值(最后一个 bin 包含两个边界)。稍微移动 bin 边界以获得与 hist 相同的 bin 计数。

edges(2:end) = edges(2:end)+eps(edges(2:end))
edges = 1×5

  -10.0000   -5.0000    0.0000    5.0000   10.0000

现在,将 histogram 与 bin 边界结合使用。

histogram(A,edges)

Figure contains an axes object. The axes object contains an object of type histogram.