Week 5 - Curve fitting
Objective:
- To write code, to fit a linear and cubic polynomial for the Cp data.
What is Curve fitting?
- Curve fitting is done in order to study the characteristic equation between a dependent and one or more independent variables. The fitting is done in order to find out which order of polynomial offers the best fit and how many regions the data can be split into in order to figure out the optimal fit for the given data points.
Python code:
- First, we have imported all the modules which are required for curve fitting.
- After, importing the modules we define the function for quadratic & cubic polynomial.
- The curve_fit command returns two value popt & pcov.
- popt is nothing but the coefficients of the polynomial
- pcov is nothing but the covariance of the coefficients which can be used to find the standard deviation of these coefficients
- np.array(temperature) basically saves the value of temperature in an array & it can be called for each coefficient in order to get Cp for each temperature.
- The * in *popt is basically used to call all the coefficients in one go instead of calling them separately.
- The following code is written to fit the curve for quadratic & cubic polynomial.
#Importting all the modules which is required for curve fit
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
import numpy as np
#Defining function for Quadratic ploynomial
def quad_fun(t,a,b,c):
return a*pow(t,2)+b*t+c
#Defining function for cubic ploynomial
def cubic_fun(t,a,b,c,d):
return a*pow(t,3)+b*pow(t,2)+c*t+d
#Creating empty array
temperature=[]
Cp=[]
line_count=1
#Extracting the data from the external file
for line in open('data','r'):
values=line.split(',')
temperature.append(float(values[0]))
Cp.append(float(values[1]))
line_count=line_count+1
#Fitting the curve for Quadratic ploynomial
popt,pcov=curve_fit(quad_fun,temperature,Cp)
Fit_Cp_quad=quad_fun(np.array(temperature),*popt)
#Fitting the curve for Quadratic ploynomial
popt,pcov=curve_fit(cubic_fun,temperature,Cp)
Fit_Cp_cubic=cubic_fun(np.array(temperature),*popt)
#Plotting
plt.figure()
plt.plot(temperature,Cp,linewidth=4,color='Blue')
plt.plot(temperature,Fit_Cp_quad,linewidth=4,color='red')
plt.xlabel('Temperature',color='Black')
plt.ylabel('Cp',color='Black')
plt.title('Curve fit for Quadratic ploynomial',fontsize=10)
plt.legend(['Actual_data','Predicited_Cp'])
plt.show()
#Plotting
plt.figure()
plt.plot(temperature,Cp,linewidth=4,color='Blue')
plt.plot(temperature,Fit_Cp_cubic,linewidth=4,color='red')
plt.xlabel('Temperature',color='Black')
plt.ylabel('Cp',color='Black')
plt.title('Curve fit for Cubic ploynomial',fontsize=10)
plt.legend(['Actual_data','Predicited_Cp'])
plt.show()
Output plot:
Curve fit for Quadratic polynomial
Curve fit for Cubic Polynomial
As we can see from the above plots, the level of accuracy differs based on the order of the polynomial used. The more number of coefficients, the less the error meaning in order to have a perfect fit, the error needs to be zero. While this is physically impossible but using higher-order polynomials the errors can reduce so that the fit is optimal.
Another way to improve the fit is by using a smaller data range and plotting multiple times in order to have many linear plots rather than one curve. This can improve the level of fit for lower-order polynomials as we can see in the below code.
Python code
In the code, we have split the data into four parts and by using low order polynomial i.e quadratic one we have fit the curve.
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
import numpy as np
#Defining function for Quadratic ploynomial
def fun(t,a,b,c):
return a*pow(t,2)+b*t+c
#Creating empty array for temperature
temperature=[]
temperature1=[]
temperature=[]
temperature2=[]
temperature3=[]
temperature4=[]
#Creating empty array for Cp
Cp=[]
Cp1=[]
Cp2=[]
Cp3=[]
Cp4=[]
line_count=1
#Extracting the data from the external file
for line in open('data','r'):
values=line.split(',')
temperature.append(float(values[0]))
Cp.append(float(values[1]))
line_count=line_count+1
#Splitting the Cp into four parts
Cp1=Cp[0:800]
Cp2=Cp[800:1600]
Cp3=Cp[1600:2400]
Cp4=Cp[2400:3200]
#Splitting the temperature into four parts
temperature1=temperature[0:800]
temperature2=temperature[800:1600]
temperature3=temperature[1600:2400]
temperature4=temperature[2400:3200]
#Fitting the curve
popt1,pcov1=curve_fit(fun,temperature1,Cp1)
popt2,pcov2=curve_fit(fun,temperature2,Cp2)
popt3,pcov3=curve_fit(fun,temperature3,Cp3)
popt4,pcov4=curve_fit(fun,temperature4,Cp4)
Fit_Cp1=fun(np.array(temperature1),*popt1)
Fit_Cp2=fun(np.array(temperature2),*popt2)
Fit_Cp3=fun(np.array(temperature3),*popt3)
Fit_Cp4=fun(np.array(temperature4),*popt4)
#Plotting
plt.figure()
plt.plot(temperature,Cp,linewidth=4,color='Blue')
plt.plot(temperature1,Fit_Cp1,linewidth=4,color='red')
plt.plot(temperature2,Fit_Cp2,linewidth=4,color='red')
plt.plot(temperature3,Fit_Cp3,linewidth=4,color='red')
plt.plot(temperature4,Fit_Cp4,linewidth=4,color='red')
plt.xlabel('Temperature',color='Black')
plt.ylabel('Cp',color='Black')
plt.title('Curve fit for Quadratic ploynomial',fontsize=10)
plt.legend(['Actual_data','Predicited_Cp'])
plt.show()
Output plot:
From the above plot, it’s quite clear that even if we used low order polynomial we can get a perfect fit but for this, we should split the data as discussed earlier.