无法获取Matplotlib直方图上的yaxis以显示概率

2024-10-01 11:20:17 发布

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

我的数据(pd系列)如下(每日股票收益,n=555):

S = perf_manual.returns
S = S[~((S-S.mean()).abs()>3*S.std())]

2014-03-31 20:00:00    0.000000
2014-04-01 20:00:00    0.000000
2014-04-03 20:00:00   -0.001950
2014-04-04 20:00:00   -0.000538
2014-04-07 20:00:00    0.000764
2014-04-08 20:00:00    0.000803
2014-04-09 20:00:00    0.001961
2014-04-10 20:00:00    0.040530
2014-04-11 20:00:00   -0.032319
2014-04-14 20:00:00   -0.008512
2014-04-15 20:00:00   -0.034109
...

我想从中生成一个概率分布图。使用:

^{pr2}$

我得到以下信息:

NormaltestResult(statistic=66.587382579416982, pvalue=3.473230376732532e-15)
1.0
0.000495624926242 0.0118790391467

graph

我觉得y轴是一个计数,但我想用概率来代替。我该怎么做?我试过很多StackOverflow的答案,都搞不懂。在


Tags: 数据信息abs收益meanstatisticmanualreturns
2条回答

使用plt.hist没有简单的方法(据我所知)做到这一点。但是您可以简单地使用np.histogram对数据进行存储,然后以任何方式规范化数据。如果我理解正确,你希望数据显示在给定的箱子里找到一个点的概率,而不是概率分布。这意味着你必须缩放你的数据,所有箱子的总和是1。这可以通过做bin_probability = n/float(n.sum())来实现。在

你将不再有一个适当规范化的概率分布函数(pdf),这意味着在区间上的积分将不再是一个概率!这就是为什么你必须重新缩放你的mlab.normpdf以获得与直方图相同的标准。所需的系数仅为bin宽度,因为当您从正确规范化的binned pdf开始时,所有bin的总和乘以它们各自的宽度为1。现在你想要的是箱数之和等于1。所以比例因子就是箱子的宽度。在

因此,您最终得到的代码大致如下:

import numpy as np
import scipy.stats as stats
import matplotlib.pyplot as plt
import matplotlib.mlab as mlab

# Produce test data
S = np.random.normal(0, 0.01, size=1000)

# Histogram:
# Bin it
n, bin_edges = np.histogram(S, 100)
# Normalize it, so that every bins value gives the probability of that bin
bin_probability = n/float(n.sum())
# Get the mid points of every bin
bin_middles = (bin_edges[1:]+bin_edges[:-1])/2.
# Compute the bin-width
bin_width = bin_edges[1]-bin_edges[0]
# Plot the histogram as a bar plot
plt.bar(bin_middles, bin_probability, width=bin_width)

# Fit to normal distribution
(mu, sigma) = stats.norm.fit(S)
# The pdf should not normed anymore but scaled the same way as the data
y = mlab.normpdf(bin_middles, mu, sigma)*bin_width
l = plt.plot(bin_middles, y, 'r', linewidth=2)

plt.grid(True)
plt.xlim(-0.05,0.05)
plt.show()

结果是:

enter image description here

当然,jotasi的答案是可行的,但是我想添加一个非常简单的技巧,通过直接调用hist来实现这一点。在

诀窍是使用weights参数。默认情况下,传递的每个数据点的权重为1。每个存储单元的高度就是落入该存储单元的数据点的权重之和。相反,如果我们有n点,我们可以简单地使每个点的权重为1 / n。在桶的重量的某一点上落下的概率,也是给定的。在

在这种情况下,只需将绘图线更改为:

n, bins, patches = plt.hist(S, weights=np.ones_like(S) / len(S),
                            facecolor='blue', alpha=0.75)

相关问题 更多 >