尝试拟合高斯分布:错误 scipy/optimize/minpack.py",第 765 行,在 curve_fit raise ValueError("`sigma` has incorrect shape.")
Attempt of fit a Gaussian distribution : Error scipy/optimize/minpack.py", line 765, in curve_fit raise ValueError("`sigma` has incorrect shape.")
我有一个众所周知的问题,但目前无法解决。
这是关于 curve_fit
函数:我得到错误:
Error scipy/optimize/minpack.py", line 765, in curve_fit raise ValueError("`sigma` has incorrect shape.")
这是代码,不要对循环 for 小心,它只是我想要 5 个不同的直方图:
for i in range(5):
mean_o[i] = np.mean(y3[:,i])
sigma_o[i] = np.std(y3[:,i])
## Histograms
# Number of bins
Nbins=100
binwidth = np.zeros(5)
# Fitting curves
def gaussian(x, a, mean, sigma):
return a * np.exp(-((x - mean)**2 / (2 * sigma**2)))
for i in range(5):
binwidth[i] = (max(y3[:,i]) - min(y3[:,i]))/Nbins
bins_plot = np.arange(min(y3[:,i]), max(y3[:,i]) + binwidth[i], binwidth[i])
plt.title('Distribution of O observable for redshift bin = '+str(z_ph_fid[i]))
plt.hist(y3[:,i], bins=bins_plot, label='bin '+str(z_ph_fid[i]))
plt.legend(loc='upper right')
# Fitting and plot
range_fit = np.linspace(min(y3[:,i]), max(y3[:,i]), len(y3[:,i]))
popt, pcov = curve_fit(gaussian, range_fit, y3[:,i], mean_o[i], sigma_o[i])
plt.plot(range_fit, gaussian(range_fit, *popt))
# Save figure
plt.savefig('chi2_gaussian_bin_'+str(i+1)+'.png')
plt.close()
第一个直方图 i=0
看起来像:
我想在直方图上绘制红色高斯拟合。
如果有人可以帮我解决这个错误...
OP 有两个问题。
第一个问题是代码试图使随机样本符合正态分布。这是错误的。不过,可以拟合直方图的输出。这显示在下面的代码中。更好的方法是使用 scipy.stats.norm.fit()
来拟合随机样本。这也显示了。
第二个问题是sigma-shape。这里 curve_fit
实际上是期待 y-data 上的错误,这自然需要 y-data 的形状。应该做的是:为拟合提供起始值。这也显示在下面。
代码如下:
import matplotlib.pyplot as plt
import numpy as np
from scipy.stats import norm
from scipy.optimize import curve_fit
mean_o = list()
sigma_o = list()
y3 = list()
### generate some data
for i in range( 5 ):
y3.append( norm.rvs( size=150000 ) )
y3 = np.transpose( y3 )
for i in range(5):
mean_o.append( np.mean( y3[ :, i ] ) )
sigma_o.append( np.std( y3[ :, i ] ) )
## Histograms
# Number of bins
Nbins=100
binwidth = np.zeros(5)
# Fitting curves
def gaussian( x, a , mean, sigma ):
return a * np.exp( -( ( x - mean )**2 / (2 * sigma**2 ) ) )
fig = plt.figure()
ax = { i : fig.add_subplot( 2, 3, i+1) for i in range( 5 ) }
for i in range(5):
ymin = min(y3[:,i])
ymax = max(y3[:,i])
binwidth[i] = ( ymax - ymin) / Nbins
bins_plot = np.arange( ymin, ymax + binwidth[i], binwidth[i])
histdata = ax[i].hist(
y3[:,i],
bins=bins_plot,
label='bin '+str(i)
)
range_fit = np.linspace( ymin, ymax, 250)
# Fitting and plot version 1
popt, pcov = curve_fit(
gaussian,
0.5 * ( histdata[1][:-1] + histdata[1][1:] ),
histdata[0],
p0=( max(histdata[0]), mean_o[i], sigma_o[i] ) )
ax[i].plot(range_fit, gaussian( range_fit, *popt ) )
ax[i].axvline( x=mean_o[i], ls=':', c='r' )
# Fitting and plot version 2
params = norm.fit( y3[ ::, i ], loc=mean_o[i], scale=sigma_o[i] )
nth = gaussian(
range_fit,
len( y3[::, i]) * binwidth[i] / np.sqrt( 2 * np.pi ),
*params
)
ax[i].plot(range_fit, nth, ls="--" )
plt.tight_layout()
plt.show()
我有一个众所周知的问题,但目前无法解决。
这是关于 curve_fit
函数:我得到错误:
Error scipy/optimize/minpack.py", line 765, in curve_fit raise ValueError("`sigma` has incorrect shape.")
这是代码,不要对循环 for 小心,它只是我想要 5 个不同的直方图:
for i in range(5):
mean_o[i] = np.mean(y3[:,i])
sigma_o[i] = np.std(y3[:,i])
## Histograms
# Number of bins
Nbins=100
binwidth = np.zeros(5)
# Fitting curves
def gaussian(x, a, mean, sigma):
return a * np.exp(-((x - mean)**2 / (2 * sigma**2)))
for i in range(5):
binwidth[i] = (max(y3[:,i]) - min(y3[:,i]))/Nbins
bins_plot = np.arange(min(y3[:,i]), max(y3[:,i]) + binwidth[i], binwidth[i])
plt.title('Distribution of O observable for redshift bin = '+str(z_ph_fid[i]))
plt.hist(y3[:,i], bins=bins_plot, label='bin '+str(z_ph_fid[i]))
plt.legend(loc='upper right')
# Fitting and plot
range_fit = np.linspace(min(y3[:,i]), max(y3[:,i]), len(y3[:,i]))
popt, pcov = curve_fit(gaussian, range_fit, y3[:,i], mean_o[i], sigma_o[i])
plt.plot(range_fit, gaussian(range_fit, *popt))
# Save figure
plt.savefig('chi2_gaussian_bin_'+str(i+1)+'.png')
plt.close()
第一个直方图 i=0
看起来像:
我想在直方图上绘制红色高斯拟合。
如果有人可以帮我解决这个错误...
OP 有两个问题。
第一个问题是代码试图使随机样本符合正态分布。这是错误的。不过,可以拟合直方图的输出。这显示在下面的代码中。更好的方法是使用 scipy.stats.norm.fit()
来拟合随机样本。这也显示了。
第二个问题是sigma-shape。这里 curve_fit
实际上是期待 y-data 上的错误,这自然需要 y-data 的形状。应该做的是:为拟合提供起始值。这也显示在下面。
代码如下:
import matplotlib.pyplot as plt
import numpy as np
from scipy.stats import norm
from scipy.optimize import curve_fit
mean_o = list()
sigma_o = list()
y3 = list()
### generate some data
for i in range( 5 ):
y3.append( norm.rvs( size=150000 ) )
y3 = np.transpose( y3 )
for i in range(5):
mean_o.append( np.mean( y3[ :, i ] ) )
sigma_o.append( np.std( y3[ :, i ] ) )
## Histograms
# Number of bins
Nbins=100
binwidth = np.zeros(5)
# Fitting curves
def gaussian( x, a , mean, sigma ):
return a * np.exp( -( ( x - mean )**2 / (2 * sigma**2 ) ) )
fig = plt.figure()
ax = { i : fig.add_subplot( 2, 3, i+1) for i in range( 5 ) }
for i in range(5):
ymin = min(y3[:,i])
ymax = max(y3[:,i])
binwidth[i] = ( ymax - ymin) / Nbins
bins_plot = np.arange( ymin, ymax + binwidth[i], binwidth[i])
histdata = ax[i].hist(
y3[:,i],
bins=bins_plot,
label='bin '+str(i)
)
range_fit = np.linspace( ymin, ymax, 250)
# Fitting and plot version 1
popt, pcov = curve_fit(
gaussian,
0.5 * ( histdata[1][:-1] + histdata[1][1:] ),
histdata[0],
p0=( max(histdata[0]), mean_o[i], sigma_o[i] ) )
ax[i].plot(range_fit, gaussian( range_fit, *popt ) )
ax[i].axvline( x=mean_o[i], ls=':', c='r' )
# Fitting and plot version 2
params = norm.fit( y3[ ::, i ], loc=mean_o[i], scale=sigma_o[i] )
nth = gaussian(
range_fit,
len( y3[::, i]) * binwidth[i] / np.sqrt( 2 * np.pi ),
*params
)
ax[i].plot(range_fit, nth, ls="--" )
plt.tight_layout()
plt.show()