matplotlib hist 函数参数密度不起作用

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

plt.hist
density
论证不起作用。

我尝试使用

density
函数中的
plt.hist
参数来规范化图中的股票收益,但它不起作用。

以下代码对我来说效果很好,并给出了我想要的概率密度函数。

import matplotlib
import numpy as np
import matplotlib.pyplot as plt

np.random.seed(19680801)

# example data
mu = 100  # mean of distribution
sigma = 15  # standard deviation of distribution
x = mu + sigma * np.random.randn(437)

num_bins = 50

plt.hist(x, num_bins, density=1)

plt.show()

plot shows density

但是当我用股票数据尝试时,它根本不起作用。结果给出了非标准化数据。我在我的数据数组中没有发现任何异常数据。

import numpy as np
import matplotlib.pyplot as plt
fig = plt.figure()
plt.hist(returns, 50,density = True)
plt.show()
# "returns" is a np array consisting of 360 days of stock returns

density not working

python matplotlib histogram
5个回答
9
投票

这是 Matplotlib 中的一个已知问题。

错误报告中所述:pyplot.hist() 中的密度标志无法正常工作

当密度 = False 时,直方图将在 Y 轴上有计数。但当密度 = True 时,Y 轴并不意味着任何有用的东西。我认为更好的实现是将 PDF 绘制为密度 = True 时的直方图。

开发人员将此视为一项功能而不是错误,因为它保持了与 numpy 的兼容性。他们已经关闭了一些关于它的错误报告,因为它正在按预期工作。更令人困惑的是,matplotlib 网站上的示例似乎显示此功能与 y 轴一起被分配了一个有意义的值。

你想用 matplotlib 做的事情是合理的,但 matplotlib 不会让你这样做。


2
投票

这不是一个错误。 条形面积等于 1。 数字看起来很奇怪,因为你的垃圾箱尺寸很小


1
投票

既然这个问题还没有解决;基于 @user14518925 的响应实际上是正确的,这将 bin 宽度视为实际有效数字,而根据我的理解,您希望每个 bin 的宽度为 1,这样频率之和为 1。更简洁地说,您是什么看到的是:

\sum_{i}y_{i} imes ext{bin 大小} =1

而你想要的是:

\sum_{i}y_{i} =1

因此,您真正需要更改的是 y 轴上的刻度标签。一种方法是禁用密度选项:

density = false

然后除以总样本量(如您的示例所示):

import matplotlib
import numpy as np
import matplotlib.pyplot as plt

np.random.seed(19680801)

# example data
mu = 0 # mean of distribution
sigma = 0.0000625  # standard deviation of distribution
x = mu + sigma * np.random.randn(437)

fig = plt.figure()
plt.hist(x, 50, density=False)
locs, _ = plt.yticks() 
print(locs)
plt.yticks(locs,np.round(locs/len(x),3))
plt.show()

0
投票

除了 tvbc 之外,另一种方法是更改绘图上的 yticks。

import matplotlib.pyplot as plt
import numpy as np

steps = 10
bins = np.arange(0, 101, steps)
data = np.random.random(100000) * 100

plt.hist(data, bins=bins, density=True)
yticks = plt.gca().get_yticks()
plt.yticks(yticks, np.round(yticks * steps, 2))
plt.show()

0
投票

一开始我也认为这是一个问题。我认为 y 轴中显示的刻度值不应大于 1。这意味着该箱中的频率大于总频率,这根本没有任何意义。

想了一会儿,我明白了到底发生了什么。所以我们期望它返回的是概率分布函数,它只不过是 (观测到的 bin 频率)/(总频率)。但是 Matplotlib 返回的密度为 (观测到的 bin 频率)/(总频率 * 每个 bin 的长度)。如果每个 bin 的长度远小于 1,则该特定 bin 的密度可以超过 1。但直方图下的总面积仍为 1。如,所有 bin 的 sum(密度*bin_length) = sum(每个频率) /(总频率)= 1.

我希望这个解释有帮助。

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