【问题标题】:Discrepancy in histograms generated by plt.hist() [duplicate]plt.hist() 生成的直方图差异 [重复]
【发布时间】:2021-07-08 10:54:15
【问题描述】:

我需要帮助找出以下代码中生成的直方图 A 和 B 存在差异的原因。我是一名物理学家,一些同事和我注意到这一点,因为我们在 python、IDL 和 Matlab 中绘制相同的数据。 Python 和 IDL 有同样的问题,但是 Matlab 没有。 Matlab 总是重现直方图 B。

import numpy as np
import matplotlib.pyplot as plt

t = np.random.randint(-1000,1000,10**3)

# A
tA = t/1000
binsizeA = 0.05
xminA = -1
xmaxA = 1
binsA = np.arange(xminA, xmaxA+binsizeA, binsizeA)
hA, _ , _ = plt.hist(tA, bins=binsA, histtype="step", label="A")

# B
tB = t
binsizeB = 50
xminB = -1000
xmaxB = 1000
binsB = np.arange(xminB, xmaxB+binsizeB, binsizeB)
hB, _ , _ = plt.hist(tB/1000, bins=binsB/1000, histtype="step", label="B")


plt.legend()
plt.show()

print(hA==hB)

Plot showing the histograms

原始数据是带有时间标记的测量值,微秒精度保存为整数。问题似乎是当数组除以 1000(从微秒到毫秒)时。有没有办法避免这种情况?

【问题讨论】:

    标签: python-3.x matplotlib histogram


    【解决方案1】:

    我从“重新创建”场景 A 开始,但直接通过缩放 B 中的所有内容(数据 + 箱):

    C - binsB / 1000

    # C
    tC = tB / 1000
    xminC = xminB / 1000
    xmaxC = xmaxB / 1000
    binsC = binsB / 1000
    hC, _ , _ = plt.hist(tC, bins=binsC, histtype="step", label="C")
    
    assert((hB == hC).all())
    

    这会产生与hB 相同的直方图,所以问题在于binsA 的生成方式:

    binsA = np.arange(xminA, xmaxA+binsizeA, binsizeA)
    

    来自其文档字符串:

    当使用非整数步长时,例如 0.1,结果通常不会 始终如一。对于这些情况,最好使用numpy.linspace

    所以要么使用 C 路线,要么使用 linspace 来创建舍入误差较小的非整数 bin。

    D - np.linspace

    有趣的是,使用 linspace会产生浮点相等的 bin,就像 binsB / 1000 所做的那样:

    # D
    tD = t / 1000
    bincountD = 41
    xminD = -1
    xmaxD = 1
    binsD = np.linspace(xminD, xmaxD, 41)
    
    hC, _ , _ = plt.hist(tC, bins=binsC, histtype="step", label="C")
    hD, _ , _ = plt.hist(tD, bins=binsD, histtype="step", label="D")
    
    plt.legend()
    plt.show()
    

    通过检查,两个binsC 看起来都等于binsD,但它们的最低有效数字仍然不同。我可以通过binsX.round(2)“钳制”它们以产生相同的直方图。

    但总的来说,这提醒我们要实现“精确”结果是多么棘手。但请注意,这一事实在这里被放大了,因为您的所有样本一开始都是整数。如果您的数据也是浮点数,则 bin 和 samples 的值将不相同。

    【讨论】:

    • 感谢您的明确答复。我今天学了些新东西。 np.arange() 应该小心使用,np.linspace() 是一个更精确的函数。
    猜你喜欢
    • 2021-08-23
    • 2016-04-26
    • 1970-01-01
    • 2014-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-24
    相关资源
    最近更新 更多