使用matplotlib和scipy在Python中仅绘制高斯曲线的一侧

使用matplotlib和scipy在Python中仅绘制高斯曲线的一侧,python,matplotlib,scipy,gaussian,Python,Matplotlib,Scipy,Gaussian,我在第一个象限中有一组点看起来像高斯分布,我正试图用python中的高斯分布拟合它,我的代码如下: import pylab as plb import matplotlib.pyplot as plt from scipy.optimize import curve_fit from scipy import asarray as ar,exp import math x=ar([37,69,157,238,274,319,391,495,533,626,1366,1855,2821,36

我在第一个象限中有一组点看起来像高斯分布,我正试图用python中的高斯分布拟合它,我的代码如下:

import pylab as plb
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
from scipy import asarray as ar,exp
import math


x=ar([37,69,157,238,274,319,391,495,533,626,1366,1855,2821,3615,4130,4374,6453,6863,7021,
    7951,8646,9656,10464,11400])
y=ar([1.77,1.67,1.65,1.17,1.34,1.46,0.75,1,0.8,1.02,0.65,0.69,0.44,0.44,0.55,0.43,0.75,0.27,0.26,
    0.44,0.04,0.44,0.26,0.04])



n = 24                          #the number of data
mean = sum(x*y)/n                   #note this correction
sigma = math.sqrt(sum(y*(x-mean)**2)/n)        #note this correction

def gaus(x,a,x0,sigma):
    return a*exp(-(x-x0)**2/(2*sigma**2))

popt,pcov = curve_fit(gaus,x,y,p0=None, sigma=None)  #'''p0=[1,mean,sigma]'''

plt.plot(x,y,'b+:',label='data')
plt.plot(x,gaus(x,*popt),'ro:',label='fit')
plt.legend()
plt.title('Fig. 3 - Fit for Time Constant')
plt.xlabel('Time (s)')
plt.ylabel('Voltage (V)')
plt.show()
输出是:这个数字:


为什么所有的红点都在下面,还要注意,我对半高斯感兴趣,因为我的数据是这样的,所以我的y值一开始很大,然后像高斯钟形的一边一样减小。有人能告诉我如何用python拟合这条曲线吗(以防它不能拟合高斯曲线)。或者换句话说,我希望代码适合我的点的一半(左侧)高斯分布(仅在第一象限)。请注意,我的点不能像我之前尝试的那样拟合为指数递减曲线,并且在较低的“x”值下拟合不好

显然,您的数据与高斯函数不太吻合。您使用
p0=[1,1,1]
的默认初始猜测,这与
curve\u fit
在开始之前放弃的任何最佳选择都相去甚远(检查
popt=[1,1,1]
pcov=[inf,inf,inf]
的值)。您可以尝试更好的猜测(例如,
p0=[2,02000]
),但在我的系统上它不会收敛:
未找到最佳参数:函数调用数已达到maxfev=800。

若要拟合“半高斯”,请不要浮动中心位置
x0
(只需使其等于0):

除非您有特定的理由想要拟合高斯函数,为什么不对多项式进行更稳健的线性最小二乘拟合,例如:

pfit = np.polyfit(x, y, 3)
poly = np.poly1d(pfit)

谢谢,我知道它看起来不像高斯曲线,但它确实像高斯曲线的正确部分。我想问,如果可能的话,是否有一种方法可以将这样的数据集只拟合为半高斯。@PsJain啊,好吧-我已经编辑过了,为您提供了这样做的方法。现在效果非常好!非常感谢您快速准确的回复!
pfit = np.polyfit(x, y, 3)
poly = np.poly1d(pfit)