The scipy.optimize module contains function that can be used to perform data fitting.
The easiest function to use is the curve_fit function. Below is the documentation of the function.
Use non-linear least squares to fit a function, f, to data.
Assumes ydata = f(xdata, *params) + eps
The algorithm uses the Levenburg-Marquardt algorithm: scipy.optimize.leastsq. Additional keyword arguments are passed directly to that algorithm.
>>> import numpy as np
>>> from scipy.optimize import curve_fit
>>> def func(x, a, b, c):
... return a*np.exp(-b*x) + c
>>> x = np.linspace(0,4,50)
>>> y = func(x, 2.5, 1.3, 0.5)
>>> yn = y + 0.2*np.random.normal(size=len(x))
>>> popt, pcov = curve_fit(func, x, yn)
The curve_fit function described above is used to minimize the following :
Indeed, it assumes that f(x[i], ...) = f(x, ...)[i] and uses the second method. Therefore, as long as the function func returns a 1D array, the curve_fit will return the optimal parameters that minimize the sum. The parameter x does not have to be a 1D array.
In order to fit pictures (2D array), one has to flatten the image array and creates the corresponding x and y coordinate. This can be done using the following code :
# image is a 2D array
ny, nx = image.shape
X,Y = meshgrid(range(nx), range(ny))
# two column matrices with X and Y
XY = array([X.flatten(), Y.flatten()]).transpose()
The XY array can be passed as the first parameter of the fit function. The fit function should then extract the corresponding x and y coordinates. For example :
def gauss(XY, amplitude, center_x, center_y, diameter):
x = XY[:,0]
y = XY[:,1]
return amplitude*exp(-((x-center_x)**2 + (y-center_y))/diameter**2)
popt, pcov = curve_fit(gauss, XY, image.flatten(), p0)
Note also that, because we have flattened the 2D array, you can select the points for your fit without keeping a matrix like structure. The following example will perform the fit only for points in the image with a positive intensity.
fimage = image.flatten()
condition = fimage>0
popt, pcov = curve_fit(gauss, XY[condition, :], fimage[condition], p0)