LMFit
LMFit is a Python library providing a high-level interface for non-linear least-squares minimization and curve fitting. It extends and builds upon `scipy.optimize` by introducing `Parameter` objects, which simplify the process of defining, constraining, and managing fitting variables. Currently at version 1.3.4, `lmfit` maintains an active development cycle with regular releases addressing bug fixes, new features, and dependency updates.
Warnings
- breaking Since version 1.0.3, the `guess()` method of `lmfit.Model` (and built-in models) now explicitly requires the `x` (independent variable) argument, even if it worked without it in older versions. Scripts not providing `x` will raise an error.
- gotcha Fit procedures will stop if `NaN` values are encountered in the objective function or model output. If `NaN`s are present in your input data and are meant to represent missing values, they must be explicitly handled.
- gotcha Parameters can sometimes get 'stuck' at their initial values or fail to converge if small changes to their values do not significantly affect the residual (e.g., discrete steps in the model, or initial guesses are extremely far from the true minimum).
- deprecated Older Python versions are no longer supported. For instance, `lmfit` version 1.2.0 dropped support for Python 3.6, and version 1.3.3 dropped support for Python 3.8. The current minimum required Python version is 3.9.
- gotcha When using `lmfit.minimize` directly (rather than `Model.fit`), the `Parameters` object passed as an argument can be modified in-place by the minimization routine. Reusing the same `Parameters` object for multiple fits without explicit copying can lead to unexpected results.
Install
-
pip install lmfit
Imports
- Model
from lmfit import Model
- Parameters
from lmfit import Parameters
- minimize
from lmfit import minimize
Quickstart
import numpy as np
from lmfit import Model
# 1. Generate some data
x = np.linspace(0, 10, 100)
y_true = 3.0 * np.exp(-0.5 * x) + 2.0
np.random.seed(0)
y_data = y_true + np.random.normal(0, 0.2, x.shape)
# 2. Define your model function
def exponential_decay(x, amplitude, decay, offset):
return amplitude * np.exp(-decay * x) + offset
# 3. Create a Model instance from your function
exp_model = Model(exponential_decay)
# 4. Create initial parameters with guess() or manually
# guess() method often requires x and y data for good initial estimates
params = exp_model.make_params(amplitude=5., decay=0.1, offset=1.)
# Or, for more refined control:
# params = exp_model.guess(y_data, x=x)
# Optionally set bounds or fix parameters
params['amplitude'].set(min=0.0)
params['decay'].set(min=0.0)
# 5. Fit the model to the data
result = exp_model.fit(y_data, params, x=x)
# 6. Print the fitting report
print(result.fit_report())
# You can also access best-fit parameters, statistics, etc.
# print(f"Best-fit amplitude: {result.params['amplitude'].value:.3f}")
# print(f"Reduced Chi-square: {result.redchi:.3f}")