Scipy 非常奇怪地拟合并创建了多条拟合曲线,但事实并非如此,我知道曲线拟合不会 return 多条曲线

Scipy fits very weirdly and creates multiple fitted curves which shouldn't be the case and I know curve fitting doesn't return multiple curves

这是我的代码

yp = df.final_sulfur/df.start_sulfur
xp = df.mag/df.hm_weight
sns.set(font_scale=1.5, font='DejaVu Sans')
fig, ax = plt.subplots(1,1, figsize=(9, 9))
yp = df.final_sulfur/df.start_sulfur
xp = df.mag/df.hm_weight
p = ax.plot(xp, yp, marker='o', markersize=1, alpha=0.2, linestyle='none')
p = ax.set_xlabel('mag/hm_weight')
p = ax.set_ylabel('final/start sulfur')
p = ax.set_title('final S vs mag')
p = ax.set_xlim(0.08, 12)
p = ax.set_ylim(3.0e-3, 1.5)
p = ax.set_xscale('log')
p = ax.set_yscale('log')
leg = plt.legend()

试图拟合下面的曲线是我认为指数衰减应该做的方程但是我得到的是完全糟糕的结果

import scipy as sp
from scipy.optimize import curve_fit
def func(xp, a, b, c):
    return a*np.exp(-b*xp) + c  
popt2, pcov2 = curve_fit(func, xp, yp, p0=None)
a2, b2, c2 = popt2
print ('a2=', a2, 'b2=', b2, 'c2=', c2)
print ('func=', func(xp, a2, b2, c2))
ax.plot(xp, func(xp, *popt2), 'b-', label='Fit',linestyle='--',color='red')

注意:我需要使用对数刻度来绘图,这是有意义的

我的样本数据是什么样子的(很遗憾,很难将所有数据放在这里) xp(示例)为了 SO

转换为列表
[1.8535530937584435,
 0.3220338983050847,
 1.184544992374174,
 0.7583873696081196,
 0.3209681662720337,
 1.158380317785751,
 1.6285714285714286,
 0.44209925841414716,
 0.7396205664008799,
 0.27983539094650206,
 0.575319622012229,
 0.3287671232876712,
 1.382921589688507,
 0.8247978436657682,
 1.315934065934066,
 0.23450134770889489,
 0.5697069296083265,
 1.0015731515469324,
 1.2841602547094721,
 0.645600653772814,
 0.4599483204134367,
 0.8340260459961208,
 0.8992900341835393,
 0.961340206185567,
 0.5845225027442371,
 0.9623773173391493,
 1.3451708366962605,
 0.8418230563002681,
 0.7456025203465477,
 1.9345156889495225]
 yp [0.05202312138728324,
 0.47058823529411764,
 0.04833333333333333,
 0.11392405063291139,
 0.36363636363636365,
 0.020588235294117647,
 0.008823529411764706,
 0.25641025641025644,
 0.12,
 0.47826086956521735,
 0.1826923076923077,
 0.3333333333333333,
 0.01282051282051282,
 0.029411764705882353,
 0.03225806451612903,
 0.26666666666666666,
 0.05,
 0.011428571428571429,
 0.12080536912751677,
 0.11764705882352941,
 0.2926829268292683,
 0.049999999999999996,
 0.06578947368421052,
 0.08024691358024691,
 0.15517241379310343,
 0.024390243902439025,
 0.017543859649122806,
 0.05479452054794521,
 0.03571428571428571,
 0.007142857142857143]

这就是我愿意获得更好的指数衰减曲线的方式

yp = df.final_sulfur/df.start_sulfur
xp = df.mag/df.hm_weight
test_data=xp.to_frame(name = 'xp').join(yp.to_frame(name='yp'))
sns.set(font_scale=1.5, font='DejaVu Sans')
fig, ax = plt.subplots(1,1, figsize=(9,15))
yp = df.final_sulfur/df.start_sulfur
xp = df.mag/df.hm_weight
p = ax.plot(xp, yp, marker='o', markersize=1, alpha=0.2, linestyle='none')
#p = sns.regplot(x=xp, y=yp, data=test_data,logx=True)
model = lambda x, A, x0, sigma, offset:  offset+A*np.exp(-((x-x0)/sigma)**1)
popt, pcov = curve_fit(model, xp.values, yp.values, p0=[0,0.5,1,1])
x = np.linspace(xp.values.min(),xp.values.max())
p =ax.plot(x,model(x,*popt), label="fit",color='red',linestyle='--')
model2 = lambda x, sigma:  model(x,0.5,0,sigma**1,0)
x2 = np.linspace(xp.values.min(),xp.values.max())
popt2, pcov2 = curve_fit(model2, xp.values, 
                              yp.values, p0=[1])
p= ax.plot(x2,model2(x2,*popt2), label="fit2",color='green')
model3 = lambda x, A, x0, sigma, offset:  offset+A*np.exp(-((x+x0)/sigma)**1)
popt, pcov = curve_fit(model3, xp.values, yp.values, p0=[0,0.5,1,1])
x3 = np.linspace(xp.values.min(),xp.values.max())
p = ax.plot(x3,model(x3,*popt), label="fit3",color='blue')