当数据点紧密聚集时,为什么 matplotlib 会错误地显示直方图

问题描述 投票:0回答:1

我试图在直方图中显示一些数据,但是当数据聚集得太紧密时,我要么得到一张空图,要么得到一个我认为不准确的图表。

考虑以下代码:

import numpy as np
from matplotlib import pyplot as plt

# Generate data
nums = np.random.rand(1000)+1000

# Make Histogram
plt.hist(nums, bins=1000, alpha=0.6, color='blue')  
plt.xlim([900,1100])
plt.yscale('linear')
plt.grid(True)
plt.show()

这给出了下图:

但是,如果我将 xlim 值更改为:

plt.xlim([990,1010])

我得到:

如果我再次更改它,

plt.xlim([999,1001])

我明白了

由于每个箱覆盖的数字范围较小,我预计箱的峰值会减少,而不是增加。有什么我不明白的地方吗,或者这是 matplotlib 的问题吗? (注意:这似乎与matplotlib中的空直方图 - 小间隔数据非常相似,但我认为我已经更明确地提出了问题,并注意到了一个额外的问题,即使结果图不是空白的(即最高值)我的第三个地块的较窄的垃圾箱比第二个地块的垃圾箱更大)

python-3.x matplotlib histogram
1个回答
0
投票

处理随机数据时,设置种子总是一个好主意,以保证每次运行都处理相同的数据。

import numpy as np
from matplotlib import pyplot as plt

# Generate data
np.random.seed(1000)
nums = np.random.rand(1000)+1000

即使使用完全相同的数据,我们也会面临您所说的相同问题。为了说明这一点,我将用四个不同的 x 轴限制来显示我的图:

fig, axs = plt.subplots(2, 2)

bins = 100

n0, bins0, patches0 = axs[0,0].hist(nums, bins=bins, color='blue')
axs[0,0].set_xlim([900,1100])
axs[0,0].grid()

n1, bins1, patches1 = axs[0,1].hist(nums, bins=bins, color='blue')
axs[0,1].set_xlim([990,1010])
axs[0,1].grid()

n2, bins2, patches2 = axs[1,0].hist(nums, bins=bins, color='blue')
axs[1,0].set_xlim([999,1002])
axs[1,0].grid()

n3, bins3, patches3 = axs[1,1].hist(nums, bins=bins, color='blue')
axs[1,1].set_xlim([999.9,1001.1])
axs[1,1].grid()

plt.show()

是的,即使有 100 个垃圾箱而不是 1000 个垃圾箱,问题也会出现。但是如果您检查

n
bins
中的信息,它们都是相同的(应该如此,因为情节完全相同).

可以通过执行来检查

print((n0 == n1).all() and (n0 == n2).all() and (n0 == n3).all())
# True

如果数据相同但绘图不同,则这似乎是一个低分辨率问题。在这里你可以看到另外两张图片:

  • 这个之前有一个

    fig.set_size_inches(10, 5)
    plt.show

  • 这个之前有一个

    fig.set_size_inches(100, 50)
    plt.show

您可以在本地电脑上以更高的分辨率尝试此操作,但这实际上可以解决问题。

对于低分辨率的图形,要绘制的箱数多于正在使用的像素,因此

matplotlib
必须进行某种数据采样。这就是为什么每次放大或缩小绘图都会发生变化的原因。
如果您为绘图设置更大的大小,它将能够显示更多数量的垃圾箱,从而使您的绘图更值得信赖。

© www.soinside.com 2019 - 2024. All rights reserved.