matplotlib 为什么当分布紧密聚集时直方图显示不正确?[重复]

of1yzvn4  于 2023-11-22  发布在  其他
关注(0)|答案(2)|浏览(146)

此问题在此处已有答案

Bar plot with irregular spacing(1个答案)
3天前关闭。
我试图在直方图中显示一些数据,但是当数据过于紧密地聚集时,我得到的要么是一个空图,要么是一个我认为不准确的图。
下面是一个例子:

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])


我得到



由于每个bin覆盖的数字范围较小,我本以为bin的峰值会减少,而不是增加。这里有什么我不明白的地方吗?或者这是matplotlib的问题?(注:这似乎与Empty histogram in matplotlib - data in small interval非常相似,但我认为我已经更明确地阐述了这个问题,并注意到一个额外的问题,即使结果图不是空白的(即,对于我的第三个图中较窄的箱,箱的最高值大于第二个)

ojsjcaue

ojsjcaue1#

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

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个箱子也会出现问题。但是如果你检查nbins中的信息,它们都是一样的(因为它们应该是一样的,因为图是完全一样的)。
我们可以通过

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


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

  • 这个在plt.show

    之前有一个fig.set_size_inches(10, 5)
  • 这个在plt.show

    之前有fig.set_size_inches(100, 50)

您可以在本地PC上尝试使用更高的分辨率,但这实际上解决了这种情况。
对于低分辨率的图形,要绘制的bin比使用的像素要多,所以matplotlib必须进行某种数据采样,这就是为什么每次放大或缩小图形都会改变的原因。
如果您为地块设置了更大的大小,则它将能够显示更多数量的箱子,从而使您的地块更值得信赖。

hgqdbh6s

hgqdbh6s2#

  • 正如@RuthC在这条评论中所指出的:* 你的图像都是500像素左右宽。你正在丢失直方图的细节,因为你没有足够的像素来表示它。你使x轴限制越大,可用的像素就越少,所以你丢失的细节就越多。*
  • 在32英寸(2560 x 1440)显示屏上,可以看到带有xlim=[900, 1100]的100 dpi直方图条。
  • 也在Bar plot with irregular spacing中解决。注意,直方图是条形图。
import numpy as np
import matplotlib.pyplot as plt

np.random.seed(20231117)
nums = np.random.rand(1000) + 1000

xlims = [[900, 1100], [990, 1010], [999, 1001]]
dpis = [100, 300, 600]

for dpi in dpis:

    fig, axes = plt.subplots(1, 3, figsize=(20, 5), dpi=dpi)
    axes = axes.flat
    
    for ax, xlim in zip(axes, xlims):
        ax.hist(nums, bins=1000, alpha=0.6, color='blue')  
        ax.set_xlim(xlim)
        ax.set_yscale('linear')
        ax.grid(True)
    
    fig.savefig(f'00_{dpi}_test.png')

字符串

dpi=100

x1c 0d1x的数据


dpi=300



dpi=600

x1c4d 1x的


相关问题