Python - Matplotlib: 绘制概率密度函数时归一化轴
我正在使用Python和一些扩展库来获取和绘制概率密度函数。虽然我能成功绘制出来,但在调整坐标轴方面遇到了一些问题。
import decimal
import numpy as np
import scipy.stats as stats
import pylab as pl
import matplotlib.pyplot as plt
from decimal import *
from scipy.stats import norm
lines=[]
fig, ax = plt.subplots(1, 1)
mean, var, skew, kurt = norm.stats(moments='mvsk')
#Here I delete some lines aimed to fill the list with values
Long = len(lines)
Maxim = max(lines) #MaxValue
Minim = min(lines) #MinValue
av = np.mean(lines) #Average
StDev = np.std(lines) #Standard Dev.
x = np.linspace(Minim, Maxim, Long)
ax.plot(x, norm.pdf(x, av, StDev),'r-', lw=3, alpha=0.9, label='norm pdf')
weights = np.ones_like(lines)/len(lines)
ax.hist(lines, weights = weights, normed=True, histtype='stepfilled', alpha=0.2)
ax.legend(loc='best', frameon=False)
plt.show()
结果是
我希望能这样表达:
- x轴以0为中心,并与标准差相关联
- y轴与直方图和百分比(归一化为1)相关联
对于x轴,像下面这张图片
而y轴希望像最后这张图片
我已经通过单独绘制直方图并使用指令 weights = weights 来调整y轴,但在这里我无法做到。我把它放进代码里,但实际上在这种情况下没有任何作用。
任何帮助都将不胜感激
1 个回答
3
y轴的标准化方式是让曲线下的面积等于1。如果你已经用 normed=True
进行了标准化,那么给每个数据点加上相同的权重就没有意义了。
首先,你需要把数据调整到0:
lines -= mean(lines)
然后再绘制图形。
下面这个应该是一个有效的最小示例:
import numpy as np
from numpy.random import normal
import matplotlib.pyplot as plt
from scipy.stats import norm
# gaussian distributed random numbers with mu =4 and sigma=2
x = normal(4, 2, 10000)
mean = np.mean(x)
sigma = np.std(x)
x -= mean
x_plot = np.linspace(min(x), max(x), 1000)
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
ax.hist(x, bins=50, normed=True, label="data")
ax.plot(x_plot, norm.pdf(x_plot, mean, sigma), 'r-', label="pdf")
ax.legend(loc='best')
x_ticks = np.arange(-4*sigma, 4.1*sigma, sigma)
x_labels = [r"${} \sigma$".format(i) for i in range(-4,5)]
ax.set_xticks(x_ticks)
ax.set_xticklabels(x_labels)
plt.show()
输出的图像是这个:
另外,你的导入太多了。你导入了 decimals
两次,甚至有一次是用 *
导入的。还有,numpy、pyplot 和 scipy 都已经包含在 pylab 里了。为什么还要导入整个 scipy.stats,然后再单独导入其中的 norm 呢?