如何在Matplotlib hist中包含存储箱的上边界

2024-04-23 06:02:08 发布

您现在位置:Python中文网/ 问答频道 /正文

使用Matplotlib中的hist()创建直方图时,数据会按如下方式放入容器中:

lb ≤ x < ub。我如何强制它这样做:lb < x ≤ ub

此外,与Excel相比,频率表的位置降低了一个格,这导致我的测量结果不准确。使用该表作为参考,如何强制hist()使28到30之间的值落在BIN30而不是BIN25中?同样,Python中的bin 20中的值23.5也在下降,因为bin 20=20≤ x<;25)而在Excel中,bin 25=20<;x≤ 25 谢谢你的帮助

data = np.array([23.5, 28, 29, 29, 29.5, 29.5, 30, 30, 30])
bins = np.array([20, 25, 30])
# Excel               1, 8
# Python          1,  5

Tags: 数据ltbinmatplotlibnp方式直方图excel
1条回答
网友
1楼 · 发布于 2024-04-23 06:02:08

可能numpy.digitize对您来说很有趣(从文档中):

Return the indices of the bins to which each value in input array belongs.

`right`    order of bins  returned index `i` satisfies
=========  =============  ============================
``False``  increasing     ``bins[i-1] <= x < bins[i]``
``True``   increasing     ``bins[i-1] < x <= bins[i]``
``False``  decreasing     ``bins[i-1] > x >= bins[i]``
``True``   decreasing     ``bins[i-1] >= x > bins[i]``

希望这也能消除在使用垃圾箱时常见的误解。 bins对应于网格的顶点,数据点位于两个顶点/在一个箱中。因此,数据点不对应于bins数组中的一个点,而是对应于两个点。 从这个符号可以看到的另一件事是bins=[20, 25, 30]bin 1从20-25变为bin 2从25-30,也许excel中的符号不同

为自定义直方图函数使用关键字right会产生以下代码和绘图

import numpy as np
import matplotlib.pyplot as plt

data = np.array([15,
                 17, 18, 20, 20, 20,
                 23.5, 24, 25, 25,
                 28, 29, 30, 30, 30])
bins = np.array([15, 20, 25, 30])


def custom_hist(x, bins, right=False):
    x_dig = np.digitize(x, bins=bins, right=right)
    u, c = np.unique(x_dig, return_counts=True)
    h = np.zeros(len(bins), dtype=int)
    h[u] = c
    return h


plt.hist(data, bins=bins,  color='b', alpha=0.7, label='plt.hist')
# array([3., 5., 7.]

height = custom_hist(x=data, bins=bins, right=True)
width = np.diff(bins)
width = np.concatenate((width, width[-1:]))
plt.bar(bins-width, height=height, width=width,
        align='edge', color='r', alpha=0.7, label='np.digitize')
plt.legend()
# This function also allows different sized bins

custom hist

注意,在right=True的情况下15属于bin?<;x<=15 它在直方图中给出了第四个条,即使它没有显式地包含在bins中。如果不需要这样做,则必须单独处理边缘情况,并可能将值添加到第一个有效箱中。 我想这也是为什么我们会看到意想不到的结果 使用您的示例数据的行为。Matplotlib对bin应用lb ≤ x < ub,但第30个与bin 25-30关联。 如果我们再加上一个30-35号垃圾桶,我们可以看到现在第30个被放在这个垃圾桶里。我猜他们在任何地方都应用规则lb ≤ x < ub,除了在边缘,这里使用lb ≤ x ≤ ub,这也是合理的,但我们必须意识到这一点

data = np.array([23.5, 28, 29, 29, 29.5, 29.5, 30, 30, 30])
plt.hist(data, bins=np.array([20, 25, 30]),  color='b', alpha=0.7, label='[20, 25, 30]')
plt.hist(data, bins=np.array([20, 25, 30, 35]),  color='r', alpha=0.7, label='[20, 25, 30, 35]')
plt.legend()

different bins

相关问题 更多 >