Python - Matplotlib:绘制概率密度函数时如何归一化坐标轴

7

我正在使用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轴如下图所示 期望的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() 

输出的图片如下: plot outout

您导入了太多模块。 您导入了两次decimals,其中一次甚至使用了*。 然后numpy、pyplot和scipy都包含在pylab中。另外为什么要导入整个scipy.stats,然后再从中导入norm?


嗨@MaxNoe,感谢您的答案。首先,我理解了减去每个元素的平均值的想法,但由于这是一组值,这种方式不正确。我认为做 lines=[x-av for x in lines] 就可以解决这个问题。无论如何,我无法将我的代码适应那个方式,并且我能绘制图形,但结果非常糟糕。您的意思是我只需要将 ax.plot(...) 行“解析”到您的代码中吗? 请问您能否将漏掉的绘图行补充到您的解决方案中?提前致谢。 - Informatico_Sano
它失去形状是什么意思? - MaxNoe
你想要将高斯钟形曲线拟合到直方图上吗?还是只是用mu=mean(x)和sigma=std(x)绘制高斯钟形曲线? - MaxNoe
1
如果您使用scipy.stats.norm.pdf,您将只绘制一个均值为mean(x)和标准差为std(x)的高斯钟曲线。对我来说这很有效,我已经编辑了帖子。 - MaxNoe
1
你可以使用范围选项,range=[-2*sigma,2 *sigma] - MaxNoe
显示剩余8条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接