问题描述
我正在尝试对一组数据进行指数拟合:
将matplotlib.pyplot导入为plt将numpy导入为np导入scipy.optimize为optdef func(x,a,b,c):返回* np.exp(x/-b)+ cepr_data = np.loadtxt('T2_text',skiprows = 1)时间= epr_data [:, 1]强度= epr_data [:, 2]优化参数,pcov = opt.curve_fit(功能,时间,强度)打印(optimizedParameters)plt.plot(时间,强度,函数(时间,* optimizedParameters),标签=适合")plt.show()
但是我只是得到了这一步功能和这些参数:
[1.88476367e + 05 1.00000000e + 00 6.49563230e + 03]
具有"fit"的地块
以及此错误消息:
OptimizeWarning:无法估计参数的协方差warnings.warn('无法估计参数的协方差'
将matplotlib.pyplot导入为plt将numpy导入为np导入scipy.optimize为optdef func(x,a,b,c):返回* np.exp(x/-b)+ cepr_data = np.loadtxt('T2_text',skiprows = 1)时间= epr_data [:, 1]强度= epr_data [:, 2]c0 = np.mean(强度[-10:])a0 =强度[0] -c0th =时间[np.searchsorted(-intensity + c0,-0.5 * a0)]b0 = th/np.log(2)优化参数,pcov = opt.curve_fit(函数,时间,强度,p0 =(a0,b0,c0))打印(optimizedParameters)plt.plot(时间,强度,标签='数据')plt.plot(时间,函数(时间,* optimizedParameters),标签=适合")plt.legend()plt.show()
首先,修复您的 plot
函数调用.要一次调用绘制两条曲线,必须为每条曲线给出 x
和 y
值:
plt.plot(时间,强度,时间,func(时间,* optimizedParameters),label ="fit")
对于标签,两次调用 plot
可能更简单:
plt.plot(时间,强度,标签=数据")plt.plot(时间,函数(时间,* optimizedParameters),标签=适合")
如果我们拥有您的数据,则更容易解决由 curve_fit
生成的警告.但是经验表明,很有可能 curve_fit
使用的参数的默认初始猜测(全为1)只是一个非常糟糕的猜测.
尝试通过为其数值优化例程提供更好的起点来帮助 curve_fit
.以下代码显示了如何计算 a
, b
和 c
的粗略猜测.将这些参数传递给参数 p0 =(a0,b0,c0)
的 curve_fit
.
#假设时间序列足够长,以至于尾部#已变平为大约c附近的随机噪声.c0 = np.mean(强度[-10:])#假设时间[0]为0.a0 =强度[0]-c0#半衰期的粗略猜测.th =时间[np.searchsorted(-intensity + c0,-0.5 * a0)]b0 = th/np.log(2)
I'm trying to do an exponential fit with a set of data:
import matplotlib.pyplot as plt
import numpy as np
import scipy.optimize as opt
def func(x, a, b, c):
return a * np.exp(x / -b) + c
epr_data = np.loadtxt('T2_text', skiprows=1)
time = epr_data[:, 1]
intensity = epr_data[:, 2]
optimizedParameters, pcov = opt.curve_fit(func, time, intensity)
print(optimizedParameters)
plt.plot(time, intensity, func(time, *optimizedParameters), label="fit")
plt.show()
but i just get this step function and these parameters:
[1.88476367e+05 1.00000000e+00 6.49563230e+03]
the plot with "fit"
as well as this error message:
OptimizeWarning: Covariance of the parameters could not be estimated
warnings.warn('Covariance of the parameters could not be estimated'
EDIT:
i want to plot the time and first row with intensity
the graph after your suggestion
edit 2:
import matplotlib.pyplot as plt
import numpy as np
import scipy.optimize as opt
def func(x, a, b, c):
return a * np.exp(x / -b) + c
epr_data = np.loadtxt('T2_text', skiprows=1)
time = epr_data[:, 1]
intensity = epr_data[:, 2]
c0 = np.mean(intensity[-10:])
a0 = intensity[0]-c0
th = time[np.searchsorted(-intensity+c0, -0.5*a0)]
b0 = th / np.log(2)
optimizedParameters, pcov = opt.curve_fit(func, time, intensity, p0=(a0, b0, c0))
print(optimizedParameters)
plt.plot(time, intensity, label='data')
plt.plot(time, func(time, *optimizedParameters), label="fit")
plt.legend()
plt.show()
First, fix your plot
function call. To plot two curves with one call, you have to give the x
and y
values for each curve:
plt.plot(time, intensity, time, func(time, *optimizedParameters), label="fit")
For labeling, it might be simpler to call plot
twice:
plt.plot(time, intensity, label="data")
plt.plot(time, func(time, *optimizedParameters), label="fit")
It would be easier to address the warning generated by curve_fit
if we had your data. Experience shows, however, that it is most likely that the default initial guess of the parameters used by curve_fit
(which is all 1s) is just a really bad guess.
Try helping curve_fit
by giving it a better starting point for its numerical optimization routine. The following bit of code shows how you can compute rough guesses for a
, b
and c
. Pass these to curve_fit
with the argument p0=(a0, b0, c0)
.
# Assume that the time series is long enough that the tail
# has flattened out to approximately random noise around c.
c0 = np.mean(intensity[-10:])
# This assumes time[0] is 0.
a0 = intensity[0] - c0
# Rough guess of the half-life.
th = time[np.searchsorted(-intensity+c0, -0.5*a0)]
b0 = th / np.log(2)
这篇关于scipy的指数衰减仅给出阶跃函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!