2014-03-25 128 views
2

嗨我试图产生一个适合我的三个指数衰减。产生令人满意的结果我没有成功。这是我得到:http://i.imgur.com/Nx44wsS.jpgPython指数衰减curve_fit给我一个线性拟合

任何帮助,非常感谢。我的代码如下。

import pylab as plb 
import matplotlib.pyplot as plt 
import matplotlib.axes as ax 
import scipy as sp 
from scipy.optimize import curve_fit 
from matplotlib import rc 
rc('font',**{'family':'sans-serif','sans-serif':['Helvetica']}) 
## for Palatino and other serif fonts use: 
#rc('font',**{'family':'serif','serif':['Palatino']}) 
rc('text', usetex=True) 

data = plb.loadtxt('data.csv',skiprows=2) 
yp = data[:,4] 
yr = data[:,5] 
yl = data[:,6] 
x = data[:,0] 

def func(x,a,b,c): 
    return a*np.exp(-b*x) + c 

popt, pcov = curve_fit(func, x, yl,maxfev=20000) 
a = popt[0] 
b = popt[1] 
c = popt[2] 
print a 
print b 
print c 
print func(x,a,b,c) 

xf = np.linspace(0,70,100) 
yf = a*np.exp(-b*x) + c 

plt.clf() 
plt.plot(x,yf,'r-', label="Fitted Curve") 
plt.plot(x,func(x,*popt)) 

plt.plot(x,yp,'bo',label='Polished') 
plt.plot(x,yr,'ro',label='Rough') 
plt.plot(x,yl,'go',label='Lacquered') 

plt.legend() 
plt.ylabel("Temperature (K)") 
plt.xlabel("Time (min)") 
plt.show() 

回答

2

非线性拟合很困难,诀窍是你必须提供一个合理的初始猜测。

这里是一个版本的代码,它做了两配合,一个具有近似的初始猜测和一个带默认初始猜测:

import pylab as plb 
import matplotlib.pyplot as plt 
import matplotlib.axes as ax 
import scipy as sp 
from scipy.optimize import curve_fit 
from matplotlib import rc 
import numpy as np 
rc('font', **{'family':'sans-serif', 'sans-serif':['Helvetica']}) 
rc('text', usetex=True) 

# Fake data 
x = np.arange(0, 70., 2.) 
yl = 300 + 63*np.exp(-x/35.) 

def func(x, a, b, c): 
    return a*np.exp(-b*x) + c 

popt, pcov = curve_fit(func, x, yl, p0=(40, 0.012, 250), maxfev=20000) 
a, b, c = popt 
print 'a=', a, 'b=', b, 'c=', c 
print 'func=', func(x, a, b, c) 

popt2, pcov2 = curve_fit(func, x, yl, p0=None, maxfev=20000) 
a2, b2, c2 = popt2 
print 'a2=', a2, 'b2=', b2, 'c2=', c2 
print 'func=', func(x, a2, b2, c2) 

xf = np.linspace(0, 70, 100) 
yf = a*np.exp(-b*x) + c 

plt.clf() 
plt.plot(x, yf, 'r-', label="Fitted Curve") 
plt.plot(x, func(x, *popt)) 
plt.plot(x, func(x, *popt2), 'b-', label='Fit w/o guess') 

plt.plot(x, yl, 'go', label='Lacquered') 

plt.legend() 
plt.ylabel("Temperature (K)") 
plt.xlabel("Time (min)") 
plt.show() 

这里是造成千篇一律:

enter image description here

正如你所看到的,用合理的初始猜测拟合效果非常好(红线)。如果你没有提供初始猜测,scipy假设所有参数都为1,并且效果很差(蓝线)。

+0

非常感谢,这很好。我现在看到初始参数的重要性。 –