Written and maintained by CASRAI Editorial Board
Last updated
lmfit is a free, open-source Python library for non-linear optimization and curve fitting. It wraps scipy.optimize so that you describe a model as a Python function, give each fitted quantity a named Parameter that can be fixed, bounded or constrained, and get back a result object with best-fit values, standard errors, correlations and fit statistics. This page is for researchers who fit calibration curves, kinetics, spectra or dose-response data in Python and want to know how to run a fit and how to read the report. It was checked against the lmfit documentation and PyPI on 2026-11-08.
What lmfit is used for in research
The lmfit documentation describes the package as a Python library for non-linear optimization and curve fitting that builds on scipy.optimize and extends the Levenberg-Marquardt least-squares method of scipy.optimize.leastsq. Its main ideas are:
- Parameter / Parameters: each fitted quantity has a name and a value, and can be held fixed, varied, given bounds, or defined by an algebraic expression of other parameters. After a fit each parameter also carries a standard error (
stderr). - Model: wraps a Python function and extends the idea of
scipy.optimize.curve_fit. It reads the independent variable and the parameter names from the function signature. - minimize(): the lower-level route. You write a residual function and lmfit runs the fit and returns a
MinimizerResult. - Built-in models: classes such as
GaussianModel,LinearModelandExponentialModel(the models chapter of the docs has the full list).
If you are still choosing a functional form, see CASRAI’s guides to exponential regression, power regression and types of regression analysis.
Install or access
lmfit is distributed on PyPI under the BSD-3-Clause license. On 2026-11-08 PyPI and the documentation listed version 1.3.4 (released 19 July 2025), which requires Python 3.9 or later and is built on NumPy and SciPy. The documented install command is:
pip install lmfit
Documentation: lmfit.github.io/lmfit-py. Package page: pypi.org/project/lmfit. Check the package page for newer releases before pinning a version in a methods section.
Step-by-step: fit a Gaussian peak with Model
The example below follows the Gaussian example in the lmfit Model chapter. The arrays are synthetic and illustrative; replace them with your own measurements.
- Import and define the model function. The first argument is the independent variable; the remaining arguments become parameters.
import numpy as np from lmfit import Model def gaussian(x, amp, cen, wid): return (amp / (np.sqrt(2*np.pi) * wid)) * np.exp(-(x - cen)**2 / (2 * wid**2)) - Prepare data. Here, illustrative synthetic values with added noise.
rng = np.random.default_rng(0) x = np.linspace(-10, 10, 201) y = gaussian(x, 5, 1, 2) + rng.normal(scale=0.02, size=x.size) - Wrap the function in a Model.
gmodel = Model(gaussian)lmfit infers that
xis the independent variable and thatamp,cenandwidare parameters. - Fit with starting values. Pass the independent variable by keyword and an initial value for each parameter.
result = gmodel.fit(y, x=x, amp=5, cen=5, wid=1) - Print the report.
print(result.fit_report()) - Plot data, initial guess and best fit. The result exposes
result.init_fitandresult.best_fitfor this purpose. - Optionally, add bounds or constraints. Use
gmodel.set_param_hint('wid', min=0)or theParametersobject so that a physically meaningless value, such as a negative width, cannot be reached. Parameters can also be fixed or tied together by expression.
Fitted values are in result.best_values (a dictionary) and result.params. Some built-in models implement a guess() method for starting values, but not every model does.
Choosing a fitting method
The default method is leastsq (Levenberg-Marquardt). The fitting chapter lists other values for the method argument:
| Family | Values named in the docs |
|---|---|
| Least-squares (default and alternative) | leastsq (Levenberg-Marquardt), least_squares (Trust Region Reflective) |
| Global | differential_evolution, brute, basinhopping, ampgo, shgo, dual_annealing |
| Scalar minimizers | nelder, lbfgsb, powell, cg, newton, cobyla, tnc, slsqp, dogleg and the trust-* methods |
| Sampling | emcee (Markov chain Monte Carlo) |
Pass the choice as gmodel.fit(y, x=x, method='least_squares', ...). Standard errors from leastsq and least_squares come from the covariance matrix; for the other methods the docs say they are calculated only when calc_covar=True, using the numdifftools package.
Output and how to read it
fit_report() prints, in order, fit statistics, the fitted variables and, when present, parameter correlations.
| Item | What the lmfit docs say it is |
|---|---|
nfev |
Number of function evaluations. |
chisqr |
The sum of squared residuals. |
redchi |
Reduced chi-square: chisqr / (N − N_varys), where N is the number of data points and N_varys the number of varied parameters. |
aic |
Akaike information criterion: N ln(chisqr/N) + 2 N_varys. |
bic |
Bayesian information criterion: N ln(chisqr/N) + ln(N) N_varys. |
| Variables block | Each parameter as value ± stderr, percentage uncertainty and the initial value. |
| Correlations | Pairs C(a, b) with absolute correlation at or above min_correl (default 0.1). |
When comparing candidate models on the same data, the docs advise preferring the lowest redchi, aic or bic, and note that bic is the most conservative. For confidence intervals beyond the covariance-based standard error, call result.conf_interval() and print them with result.ci_report(). The report display can be tuned with show_correl, min_correl, sort_pars and correl_mode.
The docs also state the limits of the standard errors: they assume Gaussian-distributed residuals and elliptical parameter distributions. By default (scale_covar=True) the covariance is rescaled by redchi; set it to False only if your data uncertainties are known to be correct.
Troubleshooting
| Symptom | What the docs say and what to try |
|---|---|
ValueError about NaN values |
The default nan_policy is 'raise'. Use 'omit' to drop NaN points or 'propagate' to let them through; cleaning the data first is usually clearer. |
No standard errors (stderr is None, errorbars is False, covar is None) |
Uncertainties could not be determined, which the docs link to parameters sitting at bounds or variables the fit is insensitive to. Check bounds, and check whether a parameter really affects the model output. |
| Fit ends at a poor solution | The result depends on starting values. Revisit amp=5, cen=5, wid=1-style initial guesses, or try a global method from the table above. |
| Error bars look too small or too large | Check scale_covar. The default rescales by redchi; disable it only when your supplied weights are true uncertainties. |
guess() not available |
Not every model implements guess(); supply starting values yourself. |
Standard errors missing with a non-default method |
Set calc_covar=True; the docs say this uses numdifftools. |
Free alternatives
| Tool | What its documentation says |
|---|---|
scipy.optimize.curve_fit |
Fits a function f(xdata, *params) by non-linear least squares. Methods: 'lm' (unconstrained only; default without bounds), 'trf' and 'dogbox' (support bounds; 'trf' is default with bounds). Returns popt and the covariance matrix pcov; standard deviations are np.sqrt(np.diag(pcov)). If p0 is omitted, all parameters start at 1. lmfit’s Model extends this approach. |
scipy.optimize.leastsq |
The Levenberg-Marquardt routine lmfit’s default method extends. |
For a MATLAB route, see Fit in MATLAB: polyfit, fit and fittype. For smoothing without a parametric form, see LOESS regression.
FAQ
What is lmfit?
A free Python library, built on SciPy and NumPy and released under the BSD-3-Clause license, for non-linear least-squares fitting with named, boundable parameters and a detailed fit report.
How do I install lmfit?
Run pip install lmfit. Version 1.3.4 requires Python 3.9 or later.
What is the difference between lmfit and curve_fit?
The lmfit docs say Model extends scipy.optimize.curve_fit. The additions are named parameters that can be fixed, bounded or constrained by expression, a result object with fit statistics, and a choice among many solvers.
Which fit statistic should I use to compare models?
The docs advise the lowest redchi, aic or bic, with bic the most conservative.
Sources (official documentation)
- lmfit documentation home, lmfit.github.io/lmfit-py, read 2026-11-08.
- lmfit, Modeling Data and Curve Fitting, model.html, read 2026-11-08.
- lmfit, Performing Fits and Analyzing Outputs, fitting.html, read 2026-11-08.
- PyPI, lmfit project page, read 2026-11-08.
- SciPy reference, scipy.optimize.curve_fit, read 2026-11-08.







