Skip to content Skip to sidebar Skip to footer

Solving Coefficients Of Data Set Using Curve_fit From Scipy.optimize

I have an array A exported from excel, containing data values as shown. 1st column x and 2nd column y are dependent variables, while 3rd column z are independent variables (the out

Solution 1:

It seems that your dataset A contains all those curves back to back.

Instead, you could split your dataset every time A[:,0] == 0.00000000e+00. After splitting it into 6 datasets, you could fit to each separately.

But if I understand your problem correctly, you would also like the parameters a and b to be the same for every dataset, correct?

In order to help you achieve that, I'm going to shamelessly plug my symfit package, which wraps curve_fit to make such problems easier to solve.

In symfit, you would do the following::

from symfit import Fit, variables, parameters, log, exp

datasets = [A_1, A_2, ...] # I'm going to assume this holds the untangled datasets one through six

xs = variables('x_1, x_2, x_3, x_4, x_5, x_6')
ys = variables('y_1, y_2, y_3, y_4, y_5, y_6')
zs = variables('z_1, ...') # same for z
a, b = parameters('a, b')

model_dict = {
    z: a/(y * b) * log(1 + (y * b/a) * (1 - exp(- a * x))) 
        for x, y, z inzip(xs, ys, zs) 
}

This code will create a vector valued model which will allow you to fit to this system of equations simultaneously (With the same instance of a and b in each!). In order to fit, we can now simply do the following:

fit = Fit(model_dict, 
     x_1=datasets[0][:,0], x_2=datasets[1][:,0], ..., 
     y_1=datasets[0][:,1], y_2=datasets[1][:,1], ..., 
     z_1=datasets[0][:,2], z_2=datasets[1][:,2], ...
)

I didn't write everything out in full but I hope this gives you an idea of how to complete this. More info can be found in the docs: symfit docs.

As a final remark, note that I have used a symbolic exp and log, not numpy's.

Solution 2:

I've edited the code (appended below) you gave a bit just so it's cut and paste reproducible into Python, in case anyone else wants to to try it.

I'm not sure I understand your question, though. It appears x and y are your independent (not dependent) variables and z your dependent variable (i.e., the thing computed from each (x,y) pair). In this case, I'd think you'd want a three-dimensional plot - currently, if I'm reading this right, you're plotting z vs x and not showing y.

Assuming you do want to do this, I agree with the comments it'd be best if you split the separate curves apart - I would think the returns-to-zero negatively impact your fit. You can use np.where(A[:,0]==0)[0] to find the indices where x==0 and use that in a loop to split apart A - though I think np.split(A,np.where(A[:,0]==0)[0]) does it for you in one line.

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

def func(data,a,b):
    return a/(data[:,1]*b)*np.log(1+(data[:,1]*b/a)*(1-np.exp(-a*data[:,0])))

A=np.array(
(0.00000000e+00, 1.49761692e-05, 0.00000000e+00,
 8.85000000e+02, 1.49761692e-05, 6.41362500e-02,
 1.48500000e+03, 1.49761692e-05, 1.19340000e-01,
 2.09000000e+03, 1.49761692e-05, 1.58760000e-01,
 3.36000000e+03, 1.49761692e-05, 2.08080000e-01,
 3.87000000e+03, 1.49761692e-05, 2.16933750e-01,
 6.48000000e+03, 1.49761692e-05, 2.46746250e-01,
 8.22000000e+03, 1.49761692e-05, 2.54700000e-01,
 1.05300000e+04, 1.49761692e-05, 2.59470000e-01,
 1.58250000e+04, 1.49761692e-05, 2.62035000e-01,
 2.37600000e+04, 1.49761692e-05, 2.68751250e-01,
 8.18400000e+04, 1.49761692e-05, 2.92848750e-01,
 0.00000000e+00, 8.57250668e-06, 0.00000000e+00,
 6.75000000e+02, 8.57250668e-06, 4.97436412e-02,
 1.27500000e+03, 8.57250668e-06, 1.27749375e-01,
 1.88000000e+03, 8.57250668e-06, 1.88617039e-01,
 3.15000000e+03, 8.57250668e-06, 2.65089780e-01,
 3.66000000e+03, 8.57250668e-06, 2.90344849e-01,
 6.27000000e+03, 8.57250668e-06, 3.36295316e-01,
 8.01000000e+03, 8.57250668e-06, 3.42702439e-01,
 1.03200000e+04, 8.57250668e-06, 3.65205982e-01,
 1.56150000e+04, 8.57250668e-06, 3.67269626e-01,
 2.35500000e+04, 8.57250668e-06, 3.87296798e-01,
 8.16300000e+04, 8.57250668e-06, 4.43486869e-01,
 0.00000000e+00, 4.26671486e-06, 0.00000000e+00,
 4.65000000e+02, 4.26671486e-06, 2.61407250e-02,
 1.06500000e+03, 4.26671486e-06, 1.22371762e-01,
 1.67000000e+03, 4.26671486e-06, 2.19629475e-01,
 2.94000000e+03, 4.26671486e-06, 3.26680087e-01,
 3.45000000e+03, 4.26671486e-06, 3.34340662e-01,
 6.06000000e+03, 4.26671486e-06, 4.18330575e-01,
 7.80000000e+03, 4.26671486e-06, 4.50631350e-01,
 1.01100000e+04, 4.26671486e-06, 4.55053950e-01,
 1.54050000e+04, 4.26671486e-06, 4.60937587e-01,
 2.33400000e+04, 4.26671486e-06, 5.10770813e-01,
 8.14200000e+04, 4.26671486e-06, 6.12569587e-01,
 0.00000000e+00, 2.13335743e-06, 0.00000000e+00,
 8.55000000e+02, 2.13335743e-06, 1.03773150e-01,
 1.46000000e+03, 2.13335743e-06, 2.21130000e-01,
 2.73000000e+03, 2.13335743e-06, 3.45515625e-01,
 3.24000000e+03, 2.13335743e-06, 3.85634925e-01,
 5.85000000e+03, 2.13335743e-06, 4.76061300e-01,
 7.59000000e+03, 2.13335743e-06, 4.79220300e-01,
 1.51950000e+04, 2.13335743e-06, 5.24709900e-01,
 2.31300000e+04, 2.13335743e-06, 5.64829200e-01,
 8.12100000e+04, 2.13335743e-06, 6.46568325e-01,
 0.00000000e+00, 1.42359023e-06, 0.00000000e+00,
 6.45000000e+02, 1.42359023e-06, 8.03596500e-02,
 1.25000000e+03, 1.42359023e-06, 2.36700000e-01,
 2.52000000e+03, 1.42359023e-06, 4.25941650e-01,
 3.03000000e+03, 1.42359023e-06, 4.61683350e-01,
 5.64000000e+03, 1.42359023e-06, 5.99561100e-01,
 7.38000000e+03, 1.42359023e-06, 6.05952000e-01,
 9.69000000e+03, 1.42359023e-06, 6.16958550e-01,
 1.49850000e+04, 1.42359023e-06, 6.57434250e-01,
 2.29200000e+04, 1.42359023e-06, 6.45954300e-01,
 8.10000000e+04, 1.42359023e-06, 7.79689800e-01,
 0.00000000e+00, 9.36010573e-07, 0.00000000e+00,
 4.35000000e+02, 9.36010573e-07, 3.40200000e-02,
 1.04000000e+03, 9.36010573e-07, 1.91160000e-01,
 2.31000000e+03, 9.36010573e-07, 3.77640000e-01,
 2.82000000e+03, 9.36010573e-07, 4.44240000e-01,
 5.43000000e+03, 9.36010573e-07, 5.50440000e-01,
 7.17000000e+03, 9.36010573e-07, 5.36580000e-01,
 9.48000000e+03, 9.36010573e-07, 5.83740000e-01,
 1.47750000e+04, 9.36010573e-07, 5.87340000e-01,
 2.27100000e+04, 9.36010573e-07, 6.33060000e-01,
 8.07900000e+04, 9.36010573e-07, 7.36200000e-01))
A = A.reshape(len(A)/3, 3)
x= A[:,0]
y= A[:,1]
z= A[:,2]

guess = [3.0e-5, 128 ]  
print guess, 'initial guessed parameters' 

params, pcov = curve_fit(func, A[:,:2], A[:,2], guess)
print params, 'fitted parameters' 

plt.plot(x,func(A,params[0],params[1]),'-r',x,z,'o') 
plt.title('Plot') 
plt.legend(['Fit', 'Data'], loc='lower right', numpoints=1)
plt.show()

Post a Comment for "Solving Coefficients Of Data Set Using Curve_fit From Scipy.optimize"