PYTHON:Curve fitting using in-built function
Objective:
To read data from a given file and use curve fitting to analyze the data properly. Also, we have to solve the set of questions given below as part of the challenge :
- What does popt and pcov mean?
- What does np.array(temperature) do?
- What does the * in *popt mean?
- What needs to be done in order to make the curve fit perfect?
Introduction:
The data file given was carefully examined and it was observed that all the data was stored in a particular format shown in the image below :
The value before the "," is the temperature value in Kelvins and the value after is the value of specific heat(Cp) in SI units. This logic was used along with the inbuilt function for curve fitting in python and the following code was generated :
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
#curve fit functions
#linear function
def funcl(t, a, b):
return a*t +b
#quadratic function
def funcq(t, a, b, c):
return a*pow(t,2) + b*t +c
#cubic function
def funcc(t, a, b, c,d):
return a*pow(t,3) + b*pow(t,2) + c*t + d
#biquadratic function
def funcb(t, a, b, c, d, e):
return a*pow(t,4) + b*pow(t,3) + c*pow(t,2) + d*t + e
#reading the data file
def read_file():
temperature = []
cp = []
for line in open('data','r'):
#Splitting the data using the comma operator
values = line.split(',')
#sending the first and second values to temperature and Cp respectively using append
temperature.append(float(values[0]))
cp.append(float(values[1]))
return [temperature,cp]
#main program
#calling the read function
temperature,cp = read_file()
#Using inbuilt function for linear fit
popt, pcov = curve_fit(funcl,temperature,cp)
fit_cp = funcl(np.array(temperature), *popt)
#Using inbuilt function for quadratic fit
popt, pcov = curve_fit(funcq,temperature,cp)
fit_cp2 = funcq(np.array(temperature), *popt)
#Using inbuilt function for cubic fit
popt, pcov = curve_fit(funcc,temperature,cp)
fit_cp3 = funcc(np.array(temperature), *popt)
#Using inbuilt function for biquadratic fit
popt, pcov = curve_fit(funcb,temperature,cp)
fit_cp4 = funcb(np.array(temperature), *popt)
#plotting the respective curve fits
plt.plot(temperature, cp,color="blue",linewidth=3)
plt.plot(temperature, fit_cp,color="red",linewidth=2)
plt.plot(temperature, fit_cp2,color="green",linewidth=2)
plt.plot(temperature, fit_cp3,color="yellow",linewidth=2)
plt.plot(temperature, fit_cp4,color="black",linewidth=2)
plt.legend(['Actual data','linear','quadratic','cubic','biquadratic'])
plt.xlabel('Temperature [K]')
plt.ylabel('Cp [j/kg]')
plt.title('Curve fitting')
plt.show()
Results:
From the plot above, it is clear that increasing the degree of the polynomial leads to a better curve fit.
Now, after looking at the results let's come back to the challenge questions :
- What does popt and pcov mean?
popt (array) : Optimal values for the parameters so that the sum of the squared residuals of f(x) is minimized or in other words - It basically stores the value of the Co-efficients in the function.
pcov (2D array) : The estimated covariance of popt. The diagonals provide the variance of the parameter estimate. - What does np.array(temperature) do?
It creates an ndarray from any object exposing array interface, or from any method that returns an array. In our case since the data is in a non-int format we would not be able to use it in the functions defined before. If np.array is not used we will get the following error - What does the * in *popt mean?
In our case popt is storing all the value for the constants in the function. therefore, the star(*) refers to the address of all these constants so that they can be called when required. - What needs to be done in order to make the curve fit perfect?
It is evident from the plot above that increasing the degree of the polynomial will make the curve fit perfect eventually. However, other methods like using different functions on different parts of the plot might also yield good results.
References: