Project

Curve fitting using Python

Objective:

To find a good fitting function for showing the relationship between temperature and specific heat capacity at constant pressure using the practical values from the data file

Procedure:

  • First, we define a function f(x) which will be will give the relationship between the temperature (x) and Cp (y) values
  • Then, a function is defined which will read and arrange the contents of the data file
  • In the main program, we use the curvefit function from the scipy module to calculate the coefficients of x in f(x)
  • Then, we after f(x) is defined fully, we use it to calculate the theoritical values of y
  • And then, plot the curve between the actual data points and the points we get from the calculated f(x)
  • And finally, we have used the `R^2`method from statistics to calculate the goodness of fit.

where, `R^2` lies between 0 and 1. The closer its value is to 1, the better is the fit.

Here, `R^2= (SSR)/(SST)`

SSR = Sum of squares of regression or amount of variance captured by the function

SST = Sum of squares of total or amount of variance in data

Case 1: Taking f(x) as a linear equation

Code:

import math
import matplotlib.pyplot as plt
import numpy as np
from scipy.optimize import curve_fit

#define a function which will act as the fitting curve for the data points 
def func(t,a,b):
	return a*pow(t,1)+b

#function to read the data from data file
def readfile():
	temperature=[]
	cp=[]
	for line in open('data','r'):
		values=line.split(',')
		temperature.append(float(values[0]))
		cp.append(float(values[1]))

	return (temperature,cp)
	
#calling the function to read the data from the file store them in the following variables	
temperature,cp=readfile()

#invoking the curvefit function to get the values of coefficients
popt,pcov=curve_fit(func,temperature,cp)

#calculating the values of Cp from the function
fit_cp=func(np.array(temperature),*popt)

#plotting the actual curve against the curve given by the function
plt.plot(temperature,cp,'r',label='Actual')
plt.plot(temperature,fit_cp,'b',label='Calculated')
plt.title('Comparision of actual vs calculated curve')
plt.xlabel('Temperature')
plt.ylabel('Specific heat capacity at constant pressure')
plt.legend(loc='best')	
plt.show()	

#checking for goodness of fit with R^2 calculation

#mean of actual cp values 
mean_cp=sum(cp)/len(cp)

#Sum of squares of total or amount of variance in data
SST=sum(pow((np.array(cp)-mean_cp),2))

#Sum of squares of regression or amount of variance captured by the function
SSR=sum(pow((np.array(fit_cp)-mean_cp),2))

#R^2=SSR/SST
print('R Square:',SSR/SST)

Results:

Here, the curve seems to be not fitting very well with the actual values. Also, the value of `R^2`comes out to be ~0.92 and hence it has lot of scope for optimisation.

Case 2: Taking f(x) as a quadratic equation

Code:

import math
import matplotlib.pyplot as plt
import numpy as np
from scipy.optimize import curve_fit

#define a function which will act as the fitting curve for the data points 
def func(t,a,b,c):
	return a*pow(t,2)+b*pow(t,1)+c

#function to read the data from data file
def readfile():
	temperature=[]
	cp=[]
	for line in open('data','r'):
		values=line.split(',')
		temperature.append(float(values[0]))
		cp.append(float(values[1]))

	return (temperature,cp)
	
#calling the function to read the data from the file store them in the following variables	
temperature,cp=readfile()

#invoking the curvefit function to get the values of coefficients
popt,pcov=curve_fit(func,temperature,cp)

#calculating the values of Cp from the function
fit_cp=func(np.array(temperature),*popt)

#plotting the actual curve against the curve given by the function
plt.plot(temperature,cp,'r',label='Actual')
plt.plot(temperature,fit_cp,'b',label='Calculated')
plt.title('Comparision of actual vs calculated curve')
plt.xlabel('Temperature')
plt.ylabel('Specific heat capacity at constant pressure')
plt.legend(loc='best')	
plt.show()	

#checking for goodness of fit with R^2 calculation

#mean of actual cp values 
mean_cp=sum(cp)/len(cp)

#Sum of squares of total or amount of variance in data
SST=sum(pow((np.array(cp)-mean_cp),2))

#Sum of squares of regression or amount of variance captured by the function
SSR=sum(pow((np.array(fit_cp)-mean_cp),2))

#R^2=SSR/SST
print('R Square:',SSR/SST)

Results:

Here too, the curve seems to be not fitting very well with the actual values. Also, the value of `R^2`comes out to be ~0.98 and hence it has still a scope for optimisation.

Case 3: Taking f(x) as a cubic equation

Code:

import math
import matplotlib.pyplot as plt
import numpy as np
from scipy.optimize import curve_fit

#define a function which will act as the fitting curve for the data points 
def func(t,a,b,c,d):
	return a*pow(t,3)+b*pow(t,2)+c*pow(t,1)+d

#function to read the data from data file
def readfile():
	temperature=[]
	cp=[]
	for line in open('data','r'):
		values=line.split(',')
		temperature.append(float(values[0]))
		cp.append(float(values[1]))

	return (temperature,cp)
	
#calling the function to read the data from the file store them in the following variables	
temperature,cp=readfile()

#invoking the curvefit function to get the values of coefficients
popt,pcov=curve_fit(func,temperature,cp)

#calculating the values of Cp from the function
fit_cp=func(np.array(temperature),*popt)

#plotting the actual curve against the curve given by the function
plt.plot(temperature,cp,'r',label='Actual')
plt.plot(temperature,fit_cp,'b',label='Calculated')
plt.title('Comparision of actual vs calculated curve')
plt.xlabel('Temperature')
plt.ylabel('Specific heat capacity at constant pressure')
plt.legend(loc='best')	
plt.show()	

#checking for goodness of fit with R^2 calculation

#mean of actual cp values 
mean_cp=sum(cp)/len(cp)

#Sum of squares of total or amount of variance in data
SST=sum(pow((np.array(cp)-mean_cp),2))

#Sum of squares of regression or amount of variance captured by the function
SSR=sum(pow((np.array(fit_cp)-mean_cp),2))

#R^2=SSR/SST
print('R Square:',SSR/SST)

Results:

Here, the curve seems to be fitting with the actual values to a great extent. Also, the value of `R^2`comes out to be 0.9967 which is very much closer to 1 now. And hence, the result seems to be optimised.

Discussions:

As seen from the three cases, the curve fit seems to be much more optimised as the degree of polynomial is increased.

Also, here are some Q&As regarding the project:

1. What does popt and pcov mean?

Ans: popt stores the values of coefficients of x of f(x) defined above and pcov stores the estimated co-variance of popt. Its diagonals gives the variance of the parameter estimate

2. What does np.array(temperature) do?

Ans: Originally, temperature is in the form of a list and to be used in the func function, it needs to be in the array format and hence this command converts it into an array.

3. What does the * in *popt mean?

Ans: It points to the address of the coefficients stored inside popt

4. What needs to be done in order to make the curve fit perfect?

Ans: From the results, it can be seen that increasing the order of the polynomial increases the perfection of the curve.

Your portfolio, next

Ship work like this
in your own course.

Talk to a career counsellor

Free 20-minute call. We'll map the right course to where you want to work.

By submitting you agree to our Terms and Privacy Policy.

Talk to a career counsellor

Free 20-minute call. We'll map the right course to where you want to work.

By submitting you agree to our Terms and Privacy Policy.