Modeling Data and Curve Fitting - Non-Linear Least-Squares Minimization and Curve-Fitting For Python
Modeling Data and Curve Fitting - Non-Linear Least-Squares Minimization and Curve-Fitting For Python
html
Contents Download
FAQ Develop
The Model class in lmfit provides a simple and flexible approach to curve-fitting problems. Like
scipy.optimize.curve_fit, a Model uses a model function a function that is meant to calculate a model
for some phenomenon and then uses that to best match an array of supplied data. Beyond that
similarity, its interface is rather different from scipy.optimize.curve_fit, for example in that it uses
Parameters, but also offers several other important advantages.
In addition to allowing you to turn any model function into a curve-fitting method, lmfit also provides
canonical definitions for many known line shapes such as Gaussian or Lorentzian peaks and
Exponential decays that are widely used in many scientific domains. These are available in the models
module that will be discussed in more detail in the next chapter (Built-in Fitting Models in the models
module). We mention it here as you may want to consult that list before writing your own model. For
now, we focus on turning Python functions into high-level fitting models with the Model class, and
using these to fit data.
We want to use this function to fit to data y(x) represented by the arrays y and x. With
scipy.optimize.curve_fit, this would be:
1 25 5/10/2017 5:00 PM
Modeling Data and Curve Fitting Non-Linear Least-Squares Minimizat... https://lmfit.github.io/lmfit-py/model.html
That is, we create data, make an initial guess of the model values, and run scipy.optimize.curve_fit
with the model function, data arrays, and initial guesses. The results returned are the optimal values
for the parameters and the covariance matrix. Its simple and useful, but it misses the benefits of
lmfit.
With lmfit, we create a Model that wraps the gaussian model function, which automatically generates
the appropriate residual function, and determines the corresponding parameter names from the
function signature itself:
As you can see, the Model gmodel determined the names of the parameters and the independent
variables. By default, the first argument of the function is taken as the independent variable, held in
independent_vars, and the rest of the functions positional arguments (and, in certain cases, keyword
arguments see below) are used for Parameter names. Thus, for the gaussian function above, the
independent variable is x, and the parameters are named amp, cen, and wid, and all taken directly
from the signature of the model function. As we will see below, you can modify the default assignment
of independent variable / arguments and specify yourself what the independent variable is and which
function arguments should be identified as parameter names.
The Parameters are not created when the model is created. The model knows what the parameters
should be named, but not anything about the scale and range of your data. You will normally have to
make these parameters and assign initial values and other attributes. To help you do this, each model
has a make_params() method that will generate parameters with the expected names:
>>>params = gmod.make_params()
This creates the Parameters but does not automaticaly give them initial values since it has no idea
what the scale should be. You can set initial values for parameters with keyword arguments to
make_params():
or assign them (and other parameter properties) after the Parameters class has been created.
A Model has several methods associated with it. For example, one can use the eval() method to
evaluate the model or the fit() method to fit data to this model with a Parameter object. Both of these
methods can take explicit keyword arguments for the parameter values. For example, one could use
eval() to calculate the predicted function:
or with:
2 25 5/10/2017 5:00 PM
Modeling Data and Curve Fitting Non-Linear Least-Squares Minimizat... https://lmfit.github.io/lmfit-py/model.html
Admittedly, this a slightly long-winded way to calculate a Gaussian function, given that you could have
called your gaussian function directly. But now that the model is set up, we can use its fit() method
to fit this model to data, as with:
or with:
Putting everything together, (included in the examples folder with the source code) is:
#!/usr/bin/envpython
#<examples/doc_model1.py>
from numpy import sqrt, pi, exp, linspace, loadtxt
from lmfit import Model
data = loadtxt('model1d_gauss.dat')
x = data[:, 0]
y = data[:, 1]
gmodel = Model(gaussian)
result = gmodel.fit(y, x=x, amp=5, cen=5, wid=1)
print(result.fit_report())
plt.plot(x, y, 'bo')
plt.plot(x, result.init_fit, 'k')
plt.plot(x, result.best_fit, 'r')
plt.show()
#<endexamples/doc_model1.py>
which is pretty compact and to the point. The returned result will be a ModelResult object. As we will
see below, this has many components, including a fit_report() method, which will show:
[[Model]]
Model(gaussian)
[[Fit Statistics]]
#functionevals=31
#datapoints=101
#variables=3
chisquare = 3.409
reduced chisquare = 0.035
Akaike info crit = 336.264
Bayesian info crit = 328.418
[[Variables]]
amp: 5.07800631 +/ 0.064957 (1.28%) (init= 5)
cen: 5.65866112 +/ 0.010304 (0.18%) (init= 5)
wid: 0.97344373 +/ 0.028756 (2.95%) (init= 1)
[[Correlations]] (unreported correlations are < 0.100)
C(amp, wid) = 0.577
3 25 5/10/2017 5:00 PM
Modeling Data and Curve Fitting Non-Linear Least-Squares Minimizat... https://lmfit.github.io/lmfit-py/model.html
As the script shows, the result will also have init_fit for the fit with the initial parameter values and a
best_fit for the fit with the best fit parameter values. These can be used to generate the following
plot:
which shows the data in blue dots, the best fit as a solid red line, and the initial fit as a dashed black
line.
gmodel = Model(gaussian)
result = gmodel.fit(y, params, x=x, amp=5, cen=5, wid=1)
These lines clearly express that we want to turn the gaussian function into a fitting model, and then fit
the y(x) data to this model, starting with values of 5 for amp, 5 for cen and 1 for wid. In addition, all
the other features of lmfit are included: Parameters can have bounds and constraints and the result is
a rich object that can be reused to explore the model fit in detail.
The model function will normally take an independent variable (generally, the first argument) and
a series of arguments that are meant to be parameters for the model. It will return an array of
data to model some data as for a curve-fitting problem.
4 25 5/10/2017 5:00 PM
Modeling Data and Curve Fitting Non-Linear Least-Squares Minimizat... https://lmfit.github.io/lmfit-py/model.html
Notes
1. Parameter names are inferred from the function arguments, and a residual function is
automatically constructed.
2. The model function must return an array that will be the same size as the data being modeled.
Examples
The model function will normally take an independent variable (generally, the first argument) and
a series of arguments that are meant to be parameters for the model. Thus, a simple peak using a
Gaussian defined as:
>>>import numpy as np
>>>def gaussian(x, amp, cen, wid):
... return amp * np.exp((xcen)**2 / wid)
>>>gmodel = Model(gaussian)
this will automatically discover the names of the independent variables and parameters:
>>>print(gmodel.param_names, gmodel.independent_vars)
['amp','cen','wid'],['x']
Model.eval(params=None, **kwargs)
Evaluate the model with supplied parameters and keyword arguments.
Notes
1. if params is None, the values for all parameters are expected to be provided as keyword
arguments. If params is given, and a keyword argument for a parameter value is also given, the
keyword argument will be used.
2. all non-parameter arguments for the model function, including all the independent
variables will need to be passed in using keyword arguments.
5 25 5/10/2017 5:00 PM
Modeling Data and Curve Fitting Non-Linear Least-Squares Minimizat... https://lmfit.github.io/lmfit-py/model.html
Examples
Take t to be the independent variable and data to be the curve we will fit. Use keyword arguments
to set initial guesses:
Notes
1. if params is None, the values for all parameters are expected to be provided as keyword
arguments. If params is given, and a keyword argument for a parameter value is also given, the
keyword argument will be used.
2. all non-parameter arguments for the model function, including all the independent
variables will need to be passed in using keyword arguments.
3. Parameters (however passed in), are copied on input, so the original Parameter objects are
unchanged, and the updated values are in the returned ModelResult.
Model.guess(data, **kws)
6 25 5/10/2017 5:00 PM
Modeling Data and Curve Fitting Non-Linear Least-Squares Minimizat... https://lmfit.github.io/lmfit-py/model.html
This is not implemented for all models, but is available for many of the built-in models.
Notes
Should be implemented for each model subclass to run self.make_params(), update starting values
and return a Parameters object.
Raises: NotImplementedError
Model.make_params(verbose=False, **kwargs)
Create a Parameters object for a Model.
Parameters: verbose (bool, optional) Whether to print out messages (default is False).
**kwargs (optional) Parameter names and initial values.
Returns: params
Return type: Parameters
Notes
1. The parameters may or may not have decent initial values for each parameter.
2. This applies any default values or parameter hints that may have been set.
Model.set_param_hint(name, **kwargs)
Set hints to use when creating parameters with make_params() for the named parameter.
This is especially convenient for setting initial values. The name can include the models prefix or
not. The hint given can also include optional bounds and constraints (value, vary, min, max,
expr), which will be used by make_params() when building default parameters.
vary
: bool, optional
Whether the Parameter is varied during a fit (default is True).
min
: float, optional
Lower bound for value (default is numpy.inf, no lower bound).
7 25 5/10/2017 5:00 PM
Modeling Data and Curve Fitting Non-Linear Least-Squares Minimizat... https://lmfit.github.io/lmfit-py/model.html
max
: float, optional
Upper bound for value (default is numpy.inf, no upper bound).
expr
: str, optional
Mathematical expression used to constrain the value during the fit.
Example
>>>model = GaussianModel()
>>>model.set_param_hint('sigma', min=0)
Model.print_param_hints(colwidth=8)
Print a nicely aligned text-table of parameter hints.
Parameters: colwidth (int, optional) Width of each column, except for first and last columns.
func
The model function used to calculate the model.
independent_vars
List of strings for names of the independent variables.
missing
Describes what to do for missing values. The choices are:
name
Name of the model, used only in the string representation of the model. By default this will be
taken from the model function.
opts
Extra keyword arguments to pass to model function. Normally this will be determined internally
and should not be changed.
param_hints
Dictionary of parameter hints. See Using parameter hints.
8 25 5/10/2017 5:00 PM
Modeling Data and Curve Fitting Non-Linear Least-Squares Minimizat... https://lmfit.github.io/lmfit-py/model.html
param_names
List of strings of parameter names.
prefix
Prefix used for name-mangling of parameter names. The default is . If a particular Model has
arguments amplitude, center, and sigma, these would become the parameter names. Using a
prefix of g1_ would convert these parameter names to g1_amplitude, g1_center, and g1_sigma.
This can be essential to avoid name collision in composite models.
By default, the independent variable is take as the first argument to the function. You can, of course,
explicitly set this, and will need to do so if the independent variable is not first in the list, or if there
are actually more than one independent variables.
If not specified, Parameters are constructed from all positional arguments and all keyword arguments
that have a default value that is numerical, except the independent variable, of course. Importantly,
the Parameters can be modified after creation. In fact, you will have to do this because none of the
parameters have valid initial values. In addition, one can place bounds and constraints on Parameters,
or fix their values.
Here, t is assumed to be the independent variable because it is the first argument to the function. The
other function arguments are used to create parameters for the model.
If you want tau to be the independent variable in the above example, you can say so:
9 25 5/10/2017 5:00 PM
Modeling Data and Curve Fitting Non-Linear Least-Squares Minimizat... https://lmfit.github.io/lmfit-py/model.html
N<Parameter'N',None,bounds=[None:None]>
You can also supply multiple values for multi-dimensional functions with multiple independent
variables. In fact, the meaning of independent variable here is simple, and based on how it treats
arguments of the function you are modeling:
independent variable
A function argument that is not a parameter or otherwise part of the model, and that will be
required to be explicitly provided as a keyword argument for each fit with Model.fit() or
evaluation with Model.eval().
Note that independent variables are not required to be arrays, or even floating point numbers.
Here, even though N is a keyword argument to the function, it is turned into a parameter, with the
default numerical value as its initial value. By default, it is permitted to be varied in the fit the 10 is
taken as an initial value, not a fixed value. On the other hand, the check_positive keyword argument,
was not converted to a parameter because it has a boolean default value. In some sense,
check_positive becomes like an independent variable to the model. However, because it has a default
value it is not required to be given for each model evaluation or fit, as independent variables are.
10 25 5/10/2017 5:00 PM
Modeling Data and Curve Fitting Non-Linear Least-Squares Minimizat... https://lmfit.github.io/lmfit-py/model.html
f1_amplitude<Parameter'f1_amplitude',None,bounds=[None:None]>
f1_center<Parameter'f1_center',None,bounds=[None:None]>
f1_sigma<Parameter'f1_sigma',None,bounds=[None:None]>
You would refer to these parameters as f1_amplitude and so forth, and the model will know to map
these to the amplitude argument of myfunc.
1. You can supply initial values in the definition of the model function.
2. You can initialize the parameters when creating parameters with
Model.make_params().
3. You can give parameter hints with Model.set_param_hint().
4. You can supply initial values for the parameters when you use the Model.eval() or
Model.fit() methods.
Of course these methods can be mixed, allowing you to overwrite initial values at any point in the
process of defining and using the model.
To supply initial values for parameters in the definition of the model function, you can simply supply a
default value:
instead of using:
This has the advantage of working at the function level all parameters with keywords can be treated
as options. It also means that some default initial value will always be available for the parameter.
When creating parameters with Model.make_params() you can specify initial values. To do this, use
keyword arguments for the parameter names and initial values:
>>>mod = Model(myfunc)
>>>pars = mod.make_params(a=3, b=0.5)
After a model has been created, but prior to creating parameters with Model.make_params(), you can
set parameter hints. These allows you to set not only a default initial value but also to set other
11 25 5/10/2017 5:00 PM
Modeling Data and Curve Fitting Non-Linear Least-Squares Minimizat... https://lmfit.github.io/lmfit-py/model.html
parameter attributes controlling bounds, whether it is varied in the fit, or a constraint expression. To
set a parameter hint, you can use Model.set_param_hint(), as with:
>>>mod = Model(myfunc)
>>>mod.set_param_hint('a', value = 1.0)
>>>mod.set_param_hint('b', value = 0.3, min=0, max=1.0)
>>>pars = mod.make_params()
Parameter hints are discussed in more detail in section Using parameter hints.
Finally, you can explicitly supply initial values when using a model. That is, as with
Model.make_params(), you can include values as keyword arguments to either the Model.eval() or
Model.fit() methods:
These approaches to initialization provide many opportunities for setting initial values for parameters.
The methods can be combined, so that you can set parameter hints but then change the initial value
explicitly with Model.fit().
>>>mod = Model(myfunc)
>>>mod.set_param_hint('a', value = 1.0)
>>>mod.set_param_hint('b', value = 0.3, min=0, max=1.0)
Parameter hints are stored in a models param_hints attribute, which is simply a nested dictionary:
>>>print mod.param_hints
{'a':{'value':1},'b':{'max':1.0,'value':0.3,'min':0}}
You can change this dictionary directly, or with the Model.set_param_hint() method. Either way, these
parameter hints are used by Model.make_params() when making parameters.
An important feature of parameter hints is that you can force the creation of new parameters with
parameter hints. This can be useful to make derived parameters with constraint expressions. For
example to get the full-width at half maximum of a Gaussian model, one could use a parameter hint
of:
>>>mod = Model(gaussian)
>>>mod.set_param_hint('fwhm', expr='2.3548*sigma')
12 25 5/10/2017 5:00 PM
Modeling Data and Curve Fitting Non-Linear Least-Squares Minimizat... https://lmfit.github.io/lmfit-py/model.html
While a Model encapsulates your model function, it is fairly abstract and does not contain the
parameters or data used in a particular fit. A ModelResult does contain parameters and data as well as
methods to alter and re-do fits. Thus the Model is the idealized model while the ModelResult is the
messier, more complex (but perhaps more useful) object that represents a fit with a set of parameters
to data with a model.
A ModelResult has several attributes holding values for fit results, and several methods for working
with fits. These include statistics inherited from Minimizer useful for comparing different models,
including chisqr, redchi, aic, and bic.
This has many attributes and methods for viewing and working with the results of a fit using
Model. It inherits from Minimizer, so that it can be used to modify and re-run the fit for the
Model.
ModelResult methods
ModelResult.eval(params=None, **kwargs)
Evaluate model function.
ModelResult.eval_components(params=None, **kwargs)
Evaluate each component of a composite model function.
13 25 5/10/2017 5:00 PM
Modeling Data and Curve Fitting Non-Linear Least-Squares Minimizat... https://lmfit.github.io/lmfit-py/model.html
The report contains fit statistics and best-fit values with uncertainties and correlations.
See also
fit_report()
ModelResult.conf_interval(**kwargs)
Calculate the confidence intervals for the variable parameters.
Confidence intervals are calculated using the confidence.conf_interval() function and keyword
arguments (**kwargs) are passed to that function. The result is stored in the ci_out attribute so
that it can be accessed without recalculating them.
Parameters: with_offset (bool, optional) Whether to subtract best value from all other
14 25 5/10/2017 5:00 PM
Modeling Data and Curve Fitting Non-Linear Least-Squares Minimizat... https://lmfit.github.io/lmfit-py/model.html
Example
Notes
ModelResult.plot(*args, **kws)
Plot the fit results and residuals using matplotlib, if available.
The method will produce a matplotlib figure with both results of the fit and the residuals plotted.
If the fit model included weights, errorbars will also be plotted.
Parameters: datafmt (str, optional) Matplotlib format string for data points.
fitfmt (str, optional) Matplotlib format string for fitted curve.
initfmt (str, optional) Matplotlib format string for initial conditions for the fit.
xlabel (str, optional) Matplotlib format string for labeling the x-axis.
ylabel (str, optional) Matplotlib format string for labeling the y-axis.
yerr (numpy.ndarray, optional) Array of uncertainties for data array.
numpoints (int, optional) If provided, the final and initial fit curves are
15 25 5/10/2017 5:00 PM
Modeling Data and Curve Fitting Non-Linear Least-Squares Minimizat... https://lmfit.github.io/lmfit-py/model.html
evaluated not only at data points, but refined to contain numpoints points in total.
fig (matplotlib.figure.Figure, optional) The figure to plot on. The default is
None, which means use the current pyplot figure or create one if there is none.
data_kws (dict, optional) Keyword arguments passed on to the plot function for
data points.
fit_kws (dict, optional) Keyword arguments passed on to the plot function for
fitted curve.
init_kws (dict, optional) Keyword arguments passed on to the plot function for
the initial conditions of the fit.
ax_res_kws (dict, optional) Keyword arguments for the axes for the residuals
plot.
ax_fit_kws (dict, optional) Keyword arguments for the axes for the fit plot.
fig_kws (dict, optional) Keyword arguments for a new figure, if there is one
being created.
Returns:
Return A tuple with matplotlibs Figure and GridSpec objects.
type:
Notes
If yerr is specified or if the fit model included weights, then matplotlib.axes.Axes.errorbar is used
to plot the data. If yerr is not specified and the fit includes weights, yerr set to 1/self.weights
See also
ModelResult.plot_fit()
ModelResult.plot_residuals()
ModelResult.plot_fit(*args, **kws)
Plot the fit results using matplotlib, if available.
The plot will include the data points, the initial fit curve, and the best-fit curve. If the fit model
included weights or if yerr is specified, errorbars will also be plotted.
Parameters: ax (matplotlib.axes.Axes, optional) The axes to plot on. The default in None,
which means use the current pyplot axis or create one if there is none.
datafmt (str, optional) Matplotlib format string for data points.
fitfmt (str, optional) Matplotlib format string for fitted curve.
initfmt (str, optional) Matplotlib format string for initial conditions for the fit.
xlabel (str, optional) Matplotlib format string for labeling the x-axis.
ylabel (str, optional) Matplotlib format string for labeling the y-axis.
yerr (numpy.ndarray, optional) Array of uncertainties for data array.
numpoints (int, optional) If provided, the final and initial fit curves are
evaluated not only at data points, but refined to contain numpoints points in total.
16 25 5/10/2017 5:00 PM
Modeling Data and Curve Fitting Non-Linear Least-Squares Minimizat... https://lmfit.github.io/lmfit-py/model.html
data_kws (dict, optional) Keyword arguments passed on to the plot function for
data points.
fit_kws (dict, optional) Keyword arguments passed on to the plot function for
fitted curve.
init_kws (dict, optional) Keyword arguments passed on to the plot function for
the initial conditions of the fit.
ax_kws (dict, optional) Keyword arguments for a new axis, if there is one being
created.
Returns:
Return matplotlib.axes.Axes
type:
Notes
For details about plot format strings and keyword arguments see documentation of
matplotlib.axes.Axes.plot.
If yerr is specified or if the fit model included weights, then matplotlib.axes.Axes.errorbar is used
to plot the data. If yerr is not specified and the fit includes weights, yerr set to 1/self.weights
See also
ModelResult.plot_residuals()
ModelResult.plot()
ModelResult.plot_residuals(*args, **kws)
Plot the fit residuals using matplotlib, if available.
If yerr is supplied or if the model included weights, errorbars will also be plotted.
Parameters: ax (matplotlib.axes.Axes, optional) The axes to plot on. The default in None,
which means use the current pyplot axis or create one if there is none.
datafmt (str, optional) Matplotlib format string for data points.
yerr (numpy.ndarray, optional) Array of uncertainties for data array.
data_kws (dict, optional) Keyword arguments passed on to the plot function for
data points.
fit_kws (dict, optional) Keyword arguments passed on to the plot function for
fitted curve.
ax_kws (dict, optional) Keyword arguments for a new axis, if there is one being
created.
Returns:
Return matplotlib.axes.Axes
type:
Notes
17 25 5/10/2017 5:00 PM
Modeling Data and Curve Fitting Non-Linear Least-Squares Minimizat... https://lmfit.github.io/lmfit-py/model.html
For details about plot format strings and keyword arguments see documentation of
matplotlib.axes.Axes.plot.
If yerr is specified or if the fit model included weights, then matplotlib.axes.Axes.errorbar is used
to plot the data. If yerr is not specified and the fit includes weights, yerr set to 1/self.weights
See also
ModelResult.plot_fit()
ModelResult.plot()
ModelResult attributes
aic
Floating point best-fit Akaike Information Criterion statistic (see MinimizerResult the
optimization result).
best_fit
numpy.ndarray result of model function, evaluated at provided independent variables and with
best-fit parameters.
best_values
Dictionary with parameter names as keys, and best-fit values as values.
bic
Floating point best-fit Bayesian Information Criterion statistic (see MinimizerResult the
optimization result).
chisqr
Floating point best-fit chi-square statistic (see MinimizerResult the optimization result).
ci_out
Confidence interval data (see Calculation of confidence intervals) or None if the confidence
intervals have not been calculated.
covar
numpy.ndarray (square) covariance matrix returned from fit.
data
numpy.ndarray of data to compare to model.
errorbars
Boolean for whether error bars were estimated by fit.
ier
Integer returned code from scipy.optimize.leastsq.
18 25 5/10/2017 5:00 PM
Modeling Data and Curve Fitting Non-Linear Least-Squares Minimizat... https://lmfit.github.io/lmfit-py/model.html
init_fit
numpy.ndarray result of model function, evaluated at provided independent variables and with
initial parameters.
init_params
Initial parameters.
init_values
Dictionary with parameter names as keys, and initial values as values.
iter_cb
Optional callable function, to be called at each fit iteration. This must take take arguments of
(params, iter, resid, *args, **kws), where params will have the current parameter values, iter
the iteration, resid the current residual array, and *args and **kws as passed to the objective
function. See Using a Iteration Callback Function.
jacfcn
Optional callable function, to be called to calculate Jacobian array.
lmdif_message
String message returned from scipy.optimize.leastsq.
message
String message returned from minimize().
method
String naming fitting method for minimize().
model
Instance of Model used for model.
ndata
Integer number of data points.
nfev
Integer number of function evaluations used for fit.
nfree
Integer number of free parameters in fit.
nvarys
Integer number of independent, freely varying variables in fit.
params
Parameters used in fit. Will have best-fit values.
redchi
Floating point reduced chi-square statistic (see MinimizerResult the optimization result).
residual
19 25 5/10/2017 5:00 PM
Modeling Data and Curve Fitting Non-Linear Least-Squares Minimizat... https://lmfit.github.io/lmfit-py/model.html
scale_covar
Boolean flag for whether to automatically scale covariance matrix.
success
Boolean value of whether fit succeeded.
weights
numpy.ndarray (or None) of weighting values to be used in fit. If not None, it will be used as a
multiplicative factor of the residual array, so that weights*(data fit) is minimized in the least-
squares sense.
dely = result.eval_uncertainty(sigma=3)
plt.fill_between(x, result.best_fitdely, result.best_fit+dely, color="#ABABAB")
to the example fit to the Gaussian at the beginning of this chapter will give 3 sigm a bands for the
best-fit Gaussian, and produce the figure below.
20 25 5/10/2017 5:00 PM
Modeling Data and Curve Fitting Non-Linear Least-Squares Minimizat... https://lmfit.github.io/lmfit-py/model.html
"line+1dgaussian"
mod = Model(gaussian_plus_line)
But we already had a function for a gaussian function, and maybe well discover that a linear
background isnt sufficient which would mean the model function would have to be changed.
This model has parameters for both component models, and can be used as:
#!/usr/bin/envpython
#<examples/model_doc2.py>
from numpy import sqrt, pi, exp, loadtxt
from lmfit import Model
data = loadtxt('model1d_gauss.dat')
x = data[:, 0]
y = data[:, 1] + 0.25*x 1.0
print(result.fit_report())
plt.plot(x, y, 'bo')
plt.plot(x, result.init_fit, 'k')
plt.plot(x, result.best_fit, 'r')
plt.show()
#<endexamples/model_doc2.py>
21 25 5/10/2017 5:00 PM
Modeling Data and Curve Fitting Non-Linear Least-Squares Minimizat... https://lmfit.github.io/lmfit-py/model.html
[[Model]]
(Model(gaussian) + Model(line))
[[Fit Statistics]]
#functionevals=44
#datapoints=101
#variables=5
chisquare = 2.579
reduced chisquare = 0.027
Akaike info crit = 360.457
Bayesian info crit = 347.381
[[Variables]]
amp: 8.45931061 +/ 0.124145 (1.47%) (init= 5)
cen: 5.65547872 +/ 0.009176 (0.16%) (init= 5)
intercept: 0.96860201 +/ 0.033522 (3.46%) (init= 1)
slope: 0.26484403 +/ 0.005748 (2.17%) (init= 0)
wid: 0.67545523 +/ 0.009916 (1.47%) (init= 1)
[[Correlations]] (unreported correlations are < 0.100)
C(amp, wid) = 0.666
C(cen, intercept) = 0.129
On the left, data is shown in blue dots, the total fit is shown in solid red line, and the initial fit is shown
as a black dashed line. In the figure on the right, the data is again shown in blue dots, and the
Gaussian component shown as a black dashed line, and the linear component shown as a red dashed
line. These components were generated after the fit using the Models ModelResult.eval_components()
method of the result:
comps = result.eval_components()
which returns a dictionary of the components, using keys of the model name (or prefix if that is set).
This will use the parameter values in result.params and the independent variables (x) used during the
fit. Note that while the ModelResult held in result does store the best parameters and the best
estimate of the model in result.best_fit, the original model and parameters in pars are left
unaltered.
You can apply this composite model to other data sets, or evaluate the model at other values of x. You
may want to do this to give a finer or coarser spacing of data point, or to extrapolate the model
outside the fitting range. This can be done with:
22 25 5/10/2017 5:00 PM
Modeling Data and Curve Fitting Non-Linear Least-Squares Minimizat... https://lmfit.github.io/lmfit-py/model.html
In this example, the argument names for the model functions do not overlap. If they had, the prefix
argument to Model would have allowed us to identify which parameter went with which component
model. As we will see in the next chapter, using composite models with the built-in models provides a
simple way to build up complex models.
Normally, one does not have to explicitly create a CompositeModel, but can use normal Python
operators +, -, *, and / to combine components as in:
Notes
Note that when using builtin Python binary operators, a CompositeModel will automatically be
constructed for you. That is, doing:
will create a CompositeModel. Here, left will be Model(fcn1), op will be operator.add(), and right will
be another CompositeModel that has a left attribute of Model(fcn2), an op of operator.mul(), and a
right of Model(fcn3).
To use a binary operator other than +, -, *, or / you can explicitly create a CompositeModel with
the appropriate binary operator. For example, to convolve two models, you could define a simple
convolution function, perhaps as:
import numpy as np
def convolve(dat, kernel):
#simpleconvolution
npts = min(len(dat), len(kernel))
pad = np.ones(npts)
tmp = np.concatenate((pad*dat[0], dat, pad*dat[1]))
out = np.convolve(tmp, kernel, mode='valid')
noff = int((len(out) npts)/2)
return (out[noff:])[:npts]
which extends the data in both directions so that the convolving kernel function gives a valid result
over the data range. Because this function takes two array arguments and returns an array, it can be
used as the binary operator. A full script using this technique is here:
#!/usr/bin/envpython
#<examples/model_doc3.py>
23 25 5/10/2017 5:00 PM
Modeling Data and Curve Fitting Non-Linear Least-Squares Minimizat... https://lmfit.github.io/lmfit-py/model.html
import numpy as np
from lmfit import Model, CompositeModel
from lmfit.lineshapes import step, gaussian
#createdatafrombroadenedstep
npts = 201
x = np.linspace(0, 10, npts)
y = step(x, amplitude=12.5, center=4.5, sigma=0.88, form='erf')
y = y + np.random.normal(size=npts, scale=0.35)
#'mid'and'center'shouldbecompletelycorrelated,and'mid'is
#usedasanintegerindex,soaverypoorfitvariable:
pars['mid'].vary = False
#fitthismodeltodataarrayy
result = mod.fit(y, params=pars, x=x)
print(result.fit_report())
plot_components = False
#plotresults
plt.plot(x, y, 'bo')
if plot_components:
#generatecomponents
comps = result.eval_components(x=x)
plt.plot(x, 10*comps['jump'], 'k')
plt.plot(x, 10*comps['gaussian'], 'r')
else:
plt.plot(x, result.init_fit, 'k')
plt.plot(x, result.best_fit, 'r')
plt.show()
##<endexamples/model_doc3.py>
[[Model]]
(Model(jump) <function convolve at 0x109ee4488> Model(gaussian))
24 25 5/10/2017 5:00 PM
Modeling Data and Curve Fitting Non-Linear Least-Squares Minimizat... https://lmfit.github.io/lmfit-py/model.html
[[Fit Statistics]]
#functionevals=27
#datapoints=201
#variables=3
chisquare = 22.091
reduced chisquare = 0.112
Akaike info crit = 437.837
Bayesian info crit = 427.927
[[Variables]]
mid: 5 (fixed)
sigma: 0.64118585 +/ 0.013233 (2.06%) (init= 1.5)
center: 4.51633608 +/ 0.009567 (0.21%) (init= 3.5)
amplitude: 0.62654849 +/ 0.001813 (0.29%) (init= 1)
[[Correlations]] (unreported correlations are < 0.100)
C(center, amplitude) = 0.344
C(sigma, amplitude) = 0.280
Using composite models with built-in or custom operators allows you to build complex models from
testable sub-components.
25 25 5/10/2017 5:00 PM