## Pages

### Curve Fitting Example With SciPy curve_fit Function

The SciPy API offers a curve_fit() function within its optimization library for fitting data to a given function. This method utilizes non-linear least squares to fit the data and determine the optimal parameters. In this tutorial, we'll explore how to use the curve_fit() function to fit curves by employing various fitting functions in Python.

Let's begin by importing the necessary libraries.

` `
```from numpy import array, exp
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt ```
` `

We need test data to implement curve fitting in this tutorial. We can define a simple x input and y output data for this purpose. Feel free to use your own data instead.

`y = array([12, 11, 13, 15, 16, 16, 15, 14, 15, 12, 11, 12, 8, 10, 9, 7, 6]) `
`x = array(range(len(y)))`

The curve_fit funciton is primarily designed for non-linear curve fitting. It uses the least-squares optimization method to find the parameters of a specified function that best fit the provided data.

We'll define multiple functions to use in the curve_fit() function and observe their differences in fitting. You can also add or change the equations to optimize the fitting parameters for your data.

We'll use the following equations as the fitting functions:

y = ax^2 + bx + c

y = ax^3 + bx + c

y = ax^3 + bx^2 + c

y = a*exp(bx) + c

We can express them in Python as shown below.

` `
```def func1(x, a, b, c):
return a*x**2+b*x+c

def func2(x, a, b, c):
return a*x**3+b*x+c

def func3(x, a, b, c):
return a*x**3+b*x**2+c

def func4(x, a, b, c):
return a*exp(b*x)+c ```

To fit the data with curve_fit(), we need to provide the fitting function, as well as the x and y data. We can also provide initial guess parameters to improve the fitting performance. If initial guesses are not provided, curve_fit will attempt to estimate them automatically, which may work well for simple functions or well-behaved data. But for more complex cases, providing initial guesses can improve the accuracy and speed of the fitting process.
The curve_fit() function then returns the optimal parameters and estimated covariance values as output.

`params, covs = curve_fit(func1, x, y)`
` `
`print("params: ", params)`
`print("covariance: ", covs)  `
` `
`[-0.08139835  0.86364809 12.13622291] `
`[ 2.38376129e-04 -3.81401808e-03  9.53504521e-03]`
`[-3.81401808e-03  6.55534359e-02 -1.88793896e-01]`
`[ 9.53504521e-03 -1.88793896e-01  7.79966703e-01]] `
`  `

Now, we'll begin fitting the data by setting the target function, as well as the x and y data, into the curve_fit() function. We'll extract the output data, which contains the parameter values for a, b, and c. Since we're not using covariance values, we can skip that step. Then, we'll calculate the fitted y values by using the derived values of a, b, and c for each function.

```params, _ = curve_fit(func1, x, y)
a, b, c = params[0], params[1], params[2]
yfit1 = a*x**2+b*x+c

params, _  = curve_fit(func2, x, y)
a, b, c = params[0], params[1], params[2]
yfit2 = a*x**3+b*x+c

params, _  = curve_fit(func3, x, y)
a, b, c = params[0], params[1], params[2]
yfit3 = a*x**3+b*x**2+c

params, _  = curve_fit(func4, x, y)
a, b, c = params[0], params[1], params[2]
yfit4 = a*exp(x*b)+c```
`  `

Finally, we'll visualize the results in a plot to assess the differences visually.

` `
```plt.plot(x, y, 'bo', label="y-original")
plt.plot(x, yfit1, label="y=a*x^2+b*x+c")
plt.plot(x, yfit2, label="y=a*x^3+b*x+c")
plt.plot(x, yfit3, label="y=a*x^3+b*x^2*c")
plt.plot(x, yfit4, label="y=a*exp(b*x)+c")
plt.xlabel('x')
plt.ylabel('y')
plt.grid(True)
plt.show() ```

In this tutorial, we briefly explored how to fit curves using the SciPy curve_fit() function. The curve_fit() function assists in determining the parameters of the selected function that most accurately represent the provided data. Adjusting the function and providing initial guesses can enhance the curve fitting process. The full source code is listed below.

Source code listing

` `
```from numpy import array, exp
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt

y = array([12, 11, 13, 15, 16, 16, 15, 14, 15, 12, 11, 12, 8, 10, 9, 7, 6])
x = array(range(len(y)))

def func1(x, a, b, c):
return a*x**2+b*x+c

def func2(x, a, b, c):
return a*x**3+b*x+c

def func3(x, a, b, c):
return a*x**3+b*x**2+c

def func4(x, a, b, c):
return a*exp(b*x)+c

params, covs = curve_fit(func1, x, y)
print("params: ", params)
print("covariance: ", covs)

params, _ = curve_fit(func1, x, y)
a, b, c = params[0], params[1], params[2]
yfit1 = a*x**2+b*x+c

params, _  = curve_fit(func2, x, y)
a, b, c = params[0], params[1], params[2]
yfit2 = a*x**3+b*x+c

params, _  = curve_fit(func3, x, y)
a, b, c = params[0], params[1], params[2]
yfit3 = a*x**3+b*x**2+c

params, _  = curve_fit(func4, x, y)
a, b, c = params[0], params[1], params[2]
yfit4 = a*exp(x*b)+c

plt.plot(x, y, 'bo', label="y-original")
plt.plot(x, yfit1, label="y=a*x^2+b*x+c")
plt.plot(x, yfit2, label="y=a*x^3+b*x+c")
plt.plot(x, yfit3, label="y=a*x^3+b*x^2*c")
plt.plot(x, yfit4, label="y=a*exp(b*x)+c")
plt.xlabel('x')
plt.ylabel('y')
`  `