I am attempting to use scipy.optimize.curve_fit but appear to be coming across some issues. Here is my code:
import numpy as np
import matplotlib.pyplot as plt
import os
os.chdir('C:/Users/Sams PC/Desktop/')
data1=np.loadtxt('Titrations6.txt')
data2=np.loadtxt('Concentrations3.txt')
protein=data2[:,0]
ligand=data2[:,1]
b=data1.transpose()
for x in b:
def fun(kd):
return np.array((B+kd-(np.sqrt(((B+kd)**2)-4*A*C)))/2*A)
from scipy.optimize import curve_fit
intensity=[x]
xdata=[protein,ligand]
ydata=intensity
A=xdata[0]
B=xdata[0]+xdata[1]
C=xdata[1]
print (xdata)
print (ydata)
popt, pcov=curve_fit(fun,xdata,ydata, p0=(1))
Data1 is a 8x6 matrix, and data2 is a 2x6 matrix. I want my function to loop through and fit each column of data1. When I run this I get the following error:
TypeError: fun() takes 1 positional argument but 2 were given
Which I don't quite understand. I've only given fun one argument, but it's saying that it's been infact given 2 arguments. Any help would be greatly appreciated!
Edit: I've added the data I'm using below for some clarity. This is what I Get when I do print (data1) and data2.
[[0. 0. 0. 0. 0. 0.
0. 0. ]
[0. 0. 0. 0. 0. 0.
0. 0. ]
[0.41437697 0.23486582 0.3946243 0.37853352 0.35563582 0.39256528
0.32845158 0.37614817]
[0.56069666 0.47530052 0.59725788 0.65505611 0.53696339 0.56234781
0.59790931 0.61088421]
[0.80054062 0.6781974 0.79853213 0.88599716 0.80807803 0.84945185
0.82345173 0.8316841 ]
[1. 1. 1. 1. 1. 1.
1. 1. ]]
[[0.59642147 0.06 ]
[0.5859375 0.11928429]
[0.56603774 0.29296875]
[0.53003534 0.62264151]
[0.41899441 1.21908127]
[0.38861986 3.05865922]]
The main issue is you didn't specify any parameters to optimize. See scipy.optimize.curve_fit
. Also I'd recommend importing and defining functions outside your loop.
The basic form of a model function is:
def fun(independent_variable, *parameters_to_optimize):
# return a combination of the independent variable and parameters
An example:
import matplotlib.pyplot as plt
import numpy as np
from scipy.optimize import curve_fit
# Generate some noisy data
x = np.linspace(0, 10, 1000)
y = x**2 + 3*x + np.random.normal(0, 0.5, len(x))
# define the model I want to fit
def fun(x, a, b, c):
return a + b * x + c * x ** 2
popt, pcov = curve_fit(fun, x, y)
# plot
plt.plot(x, y, label='data')
plt.plot(x, fun(x, *popt), label='fitted')
plt.grid()
plt.legend()
print(popt)
# [-0.07309343 3.01359277 0.99988617]
In your example there are two mistakes:
def fun(kd):
return np.array((B+kd-(np.sqrt(((B+kd)**2)-4*A*C)))/2*A)
Without seeing the actual data, that's what I can say.