import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
from scipy.integrate import quad
from scipy.interpolate import interp1d
from scipy.optimize import curve_fit
Curve fitting is used to represent a set of data by a model function.
Recall the procedure in Excel
Python
polyfit
for polynomial fits (including linear)curve_fit
for general curve fitsp = np.polyfit(x, y, polynomial_order)
np.polyval(p, x)
polyfit
polyval
xg
data.xg = np.array([0., 1., 2., 3., 4., 5.]) # given x data
yg = np.array([0, 0.8, 0.9, 0.1, -0.8, -1.0]) # given y data
#-------------
p3 = np.polyfit(xg, yg, 3)
xx = np.linspace(0,5,1000)
yy = np.polyval(p3, xx)
plt.rc('font', size=14)
plt.plot(xg, yg, 'o')
plt.plot(xx, yy, '-')
plt.xlabel('x')
plt.ylabel('y')
plt.legend(['data', 'fit'], frameon=False);
xg = np.array([2, 3, 4, 5, 6, 7, 8])
yg = np.array([1, 2, 1, 2, 1, 2, 1])
#-------------
p6 = np.polyfit(xg, yg, 6)
xx = np.linspace(-2,12,1000)
yy = np.polyval(p6, xx)
plt.plot(xg,yg, 'o')
plt.plot(xx,yy, '-')
plt.xlabel('x')
plt.ylabel('y')
plt.legend(['data', 'fit'], frameon=False);
plt.figure()
plt.plot(xg,yg, 'o')
plt.plot(xx,yy, '-')
plt.xlabel('x')
plt.ylabel('y')
plt.legend(['data', 'fit'], frameon=False);
plt.xlim([2,8])
plt.ylim([0,4])
(0, 4)
We can fit a general function f(x; a, b, c) where f is a function of x with parameters a, b, c that we want to optimize for a set of given data.
Use curve_fit
available from from scipy.optimize import curve_fit
params, extras = curve_fit(f, xg, yg)
Fit the following function to the given data $$f(x) = a\exp(-bx) + c$$
#-------- Set some given data (normally, this is already available)
xg = np.linspace(0,4,50)
yg = 2.5*np.exp(-1.3*xg)+0.5 + 0.2*np.random.normal(size=len(xg))
#-------- Define the function with parameters: x comes first
def f(x, a, b, c) :
return a*np.exp(-b*x) + c
#-------- Do the curve fit
abc, extras = curve_fit(f, xg, yg)
a = abc[0]
b = abc[1]
c = abc[2]
xx = xg
yy = f(xx,a,b,c)
#-------- Output / plot the results
print(f"a={abc[0]:.4f}, b={abc[1]:.4f}, c={abc[2]:.4f}")
plt.plot(xg, yg, 'o')
plt.plot(xx, yy, '-')
plt.legend(['data', 'fit'], frameon=False)
plt.xlabel('x')
plt.ylabel('y');
a=2.4418, b=1.3884, c=0.5064
curve_fit
function call?help(curve_fit)
for details on this and other options.