Non-linear least-squares minimization and curve-fitting with enhanced parameter management and confidence interval estimation
—
LMFIT provides 34 built-in model classes and 30 mathematical lineshape functions covering common peak shapes, distributions, step functions, oscillators, and specialized physics functions. All built-in models include automatic parameter guessing and parameter hints for easy initialization.
Models for common peak shapes and statistical distributions used in data analysis.
# Gaussian and related models
class GaussianModel(Model):
"""Gaussian peak model: amplitude * exp(-(x-center)²/(2*sigma²))"""
def guess(self, data, x=None, **kws): ...
class Gaussian2dModel(Model):
"""2D Gaussian peak model for image/surface fitting"""
def guess(self, data, x=None, y=None, **kws): ...
class LorentzianModel(Model):
"""Lorentzian peak model: amplitude / (1 + ((x-center)/sigma)²)"""
def guess(self, data, x=None, **kws): ...
class SplitLorentzianModel(Model):
"""Asymmetric Lorentzian with different widths on each side"""
def guess(self, data, x=None, **kws): ...
class VoigtModel(Model):
"""Voigt profile (Gaussian ⊗ Lorentzian convolution)"""
def guess(self, data, x=None, **kws): ...
class PseudoVoigtModel(Model):
"""Pseudo-Voigt profile (weighted sum of Gaussian and Lorentzian)"""
def guess(self, data, x=None, **kws): ...
class MoffatModel(Model):
"""Moffat profile for astronomical point spread functions"""
def guess(self, data, x=None, **kws): ...
class Pearson4Model(Model):
"""Pearson Type IV distribution"""
def guess(self, data, x=None, **kws): ...
class Pearson7Model(Model):
"""Pearson Type VII distribution"""
def guess(self, data, x=None, **kws): ...
class StudentsTModel(Model):
"""Student's t-distribution"""
def guess(self, data, x=None, **kws): ...
class BreitWignerModel(Model):
"""Breit-Wigner (Fano) profile for resonances"""
def guess(self, data, x=None, **kws): ...
class LognormalModel(Model):
"""Log-normal distribution"""
def guess(self, data, x=None, **kws): ...
class SkewedGaussianModel(Model):
"""Skewed Gaussian distribution"""
def guess(self, data, x=None, **kws): ...
class SkewedVoigtModel(Model):
"""Skewed Voigt profile"""
def guess(self, data, x=None, **kws): ...
class DoniachModel(Model):
"""Doniach Sunjic lineshape for X-ray photoelectron spectroscopy"""
def guess(self, data, x=None, **kws): ...
class ExponentialGaussianModel(Model):
"""Exponentially modified Gaussian (EMG) for chromatography"""
def guess(self, data, x=None, **kws): ...Simple mathematical functions for baseline fitting and basic functional forms.
class ConstantModel(Model):
"""Constant value: c"""
def guess(self, data, x=None, **kws): ...
class ComplexConstantModel(Model):
"""Complex constant value"""
def guess(self, data, x=None, **kws): ...
class LinearModel(Model):
"""Linear function: slope * x + intercept"""
def guess(self, data, x=None, **kws): ...
class QuadraticModel(Model):
"""Quadratic function: a * x² + b * x + c"""
def guess(self, data, x=None, **kws): ...
class ParabolicModel(Model):
"""Alias for QuadraticModel"""
def guess(self, data, x=None, **kws): ...
class PolynomialModel(Model):
"""Arbitrary degree polynomial"""
def __init__(self, degree, **kws): ...
def guess(self, data, x=None, **kws): ...
class ExpressionModel(Model):
"""Model created from mathematical expression string"""
def __init__(self, expr, independent_vars=['x'], **kws): ...Models for exponential decay, growth, and power law relationships.
class ExponentialModel(Model):
"""Exponential: amplitude * exp(decay * x)"""
def guess(self, data, x=None, **kws): ...
class PowerLawModel(Model):
"""Power law: amplitude * x^exponent"""
def guess(self, data, x=None, **kws): ...Models for step changes and rectangular pulses.
class StepModel(Model):
"""Step function with various functional forms"""
def __init__(self, form='linear', **kws): ...
def guess(self, data, x=None, **kws): ...
class RectangleModel(Model):
"""Rectangle function between two points"""
def __init__(self, form='linear', **kws): ...
def guess(self, data, x=None, **kws): ...Models for oscillatory and wave-like data.
class DampedOscillatorModel(Model):
"""Simple damped oscillator"""
def guess(self, data, x=None, **kws): ...
class DampedHarmonicOscillatorModel(Model):
"""Damped harmonic oscillator with resonance"""
def guess(self, data, x=None, **kws): ...
class SineModel(Model):
"""Sine wave: amplitude * sin(frequency * x + shift)"""
def guess(self, data, x=None, **kws): ...Specialized models for physics applications including thermal distributions.
class ThermalDistributionModel(Model):
"""Generic thermal distribution"""
def __init__(self, form='bose', **kws): ...
def guess(self, data, x=None, **kws): ...
class BoseModel(Model):
"""Bose-Einstein distribution"""
def guess(self, data, x=None, **kws): ...
class FermiModel(Model):
"""Fermi-Dirac distribution"""
def guess(self, data, x=None, **kws): ...Specialized models for complex fitting scenarios.
class SplineModel(Model):
"""Spline interpolation model"""
def __init__(self, xknots, **kws): ...
def guess(self, data, x=None, **kws): ...Direct mathematical functions (not model classes) for use in custom models.
# Peak functions
def gaussian(x, amplitude=1.0, center=0.0, sigma=1.0): ...
def gaussian2d(x, y=0.0, amplitude=1.0, centerx=0.0, centery=0.0,
sigmax=1.0, sigmay=1.0): ...
def lorentzian(x, amplitude=1.0, center=0.0, sigma=1.0): ...
def split_lorentzian(x, amplitude=1.0, center=0.0, sigma=1.0, sigma_r=1.0): ...
def voigt(x, amplitude=1.0, center=0.0, sigma=1.0, gamma=None): ...
def pvoigt(x, amplitude=1.0, center=0.0, sigma=1.0, fraction=0.5): ...
def moffat(x, amplitude=1.0, center=0.0, sigma=1.0, beta=1.0): ...
def pearson4(x, amplitude=1.0, center=0.0, sigma=1.0, expon=1.0, skew=0.0): ...
def pearson7(x, amplitude=1.0, center=0.0, sigma=1.0, expon=1.0): ...
def breit_wigner(x, amplitude=1.0, center=0.0, sigma=1.0, q=1.0): ...
def damped_oscillator(x, amplitude=1.0, center=1.0, sigma=0.1): ...
def dho(x, amplitude=1.0, center=1.0, sigma=1.0, gamma=1.0): ...
# Distribution functions
def lognormal(x, amplitude=1.0, center=0.0, sigma=1.0): ...
def students_t(x, amplitude=1.0, center=0.0, sigma=1.0): ...
def expgaussian(x, amplitude=1.0, center=0.0, sigma=1.0, gamma=1.0): ...
def skewed_gaussian(x, amplitude=1.0, center=0.0, sigma=1.0, gamma=0.0): ...
def skewed_voigt(x, amplitude=1.0, center=0.0, sigma=1.0, gamma=None, skew=0.0): ...
def doniach(x, amplitude=1.0, center=0.0, sigma=1.0, gamma=0.0): ...
def logistic(x, amplitude=1.0, center=0.0, sigma=1.0): ...
# Physics functions
def bose(x, amplitude=1.0, center=0.0, kt=1.0): ...
def fermi(x, amplitude=1.0, center=0.0, kt=1.0): ...
def thermal_distribution(x, amplitude=1.0, center=0.0, kt=1.0, form='bose'): ...
# Step and basic functions
def step(x, amplitude=1.0, center=0.0, sigma=1.0, form='linear'): ...
def rectangle(x, amplitude=1.0, center1=0.0, sigma1=1.0,
center2=1.0, sigma2=1.0, form='linear'): ...
def exponential(x, amplitude=1.0, decay=1.0): ...
def powerlaw(x, amplitude=1.0, exponent=1.0): ...
def linear(x, slope=1.0, intercept=0.0): ...
def parabolic(x, a=0.0, b=0.0, c=0.0): ...
def sine(x, amplitude=1.0, frequency=1.0, shift=0.0): ...
def expsine(x, amplitude=1.0, frequency=1.0, shift=0.0, decay=0.0): ...
# Utility functions
def not_zero(value): ... # Ensure non-zero value to prevent division errorsimport numpy as np
from lmfit.models import GaussianModel, LinearModel, ExponentialModel
# Generate sample data with Gaussian peak on linear background
x = np.linspace(0, 20, 201)
y = (5 * np.exp(-((x-10)/2)**2) + # Gaussian peak
0.2 * x + 1 + # Linear background
np.random.normal(size=201, scale=0.1)) # Noise
# Create models
gaussian = GaussianModel(prefix='peak_')
linear = LinearModel(prefix='bg_')
# Combine models
model = gaussian + linear
# Let models guess initial parameters
params = gaussian.guess(y, x=x)
params.update(linear.guess(y, x=x))
# Fit the composite model
result = model.fit(y, params, x=x)
print(result.fit_report())from lmfit.models import ExpressionModel
# Create model from mathematical expression
expr = 'amplitude * exp(-((x - center) / width)**2) * (1 + skew * (x - center))'
model = ExpressionModel(expr)
# Set parameter hints
model.set_param_hint('amplitude', value=1, min=0)
model.set_param_hint('center', value=0)
model.set_param_hint('width', value=1, min=0.01)
model.set_param_hint('skew', value=0)
# Create parameters and fit
params = model.make_params()
result = model.fit(data, params, x=x)from lmfit.models import GaussianModel, ConstantModel
# Create multiple Gaussian peaks with shared background
peak1 = GaussianModel(prefix='p1_')
peak2 = GaussianModel(prefix='p2_')
peak3 = GaussianModel(prefix='p3_')
background = ConstantModel(prefix='bg_')
# Combine all models
model = peak1 + peak2 + peak3 + background
# Set up parameters for each peak
params = model.make_params()
# Peak 1 parameters
params['p1_amplitude'].set(value=10, min=0)
params['p1_center'].set(value=5)
params['p1_sigma'].set(value=1, min=0.1)
# Peak 2 parameters
params['p2_amplitude'].set(value=15, min=0)
params['p2_center'].set(value=10)
params['p2_sigma'].set(value=1.5, min=0.1)
# Peak 3 parameters
params['p3_amplitude'].set(value=8, min=0)
params['p3_center'].set(value=15)
params['p3_sigma'].set(value=0.8, min=0.1)
# Background
params['bg_c'].set(value=1)
# Fit the model
result = model.fit(data, params, x=x)
# Evaluate individual components
components = result.eval_components(x=x)
peak1_fit = components['p1_']
peak2_fit = components['p2_']
peak3_fit = components['p3_']
background_fit = components['bg_']from lmfit import minimize, Parameters
import lmfit.lineshapes as ls
def multi_voigt_residual(params, x, data):
"""Residual function using lineshape functions directly"""
model = (ls.voigt(x, params['v1_amp'], params['v1_cen'],
params['v1_sig'], params['v1_gam']) +
ls.voigt(x, params['v2_amp'], params['v2_cen'],
params['v2_sig'], params['v2_gam']))
return model - data
# Set up parameters
params = Parameters()
params.add('v1_amp', value=10, min=0)
params.add('v1_cen', value=5)
params.add('v1_sig', value=1, min=0.1)
params.add('v1_gam', value=1, min=0.1)
params.add('v2_amp', value=8, min=0)
params.add('v2_cen', value=10)
params.add('v2_sig', value=1.2, min=0.1)
params.add('v2_gam', value=0.8, min=0.1)
# Fit using minimize
result = minimize(multi_voigt_residual, params, args=(x, data))from lmfit.models import PolynomialModel
# Create polynomial model of specified degree
poly_model = PolynomialModel(degree=3)
# Parameters are automatically named c0, c1, c2, c3 for coefficients
params = poly_model.guess(data, x=x)
# Or set manually
params = poly_model.make_params()
params['c0'].set(value=1) # constant term
params['c1'].set(value=0) # linear term
params['c2'].set(value=0) # quadratic term
params['c3'].set(value=0) # cubic term
result = poly_model.fit(data, params, x=x)Install with Tessl CLI
npx tessl i tessl/pypi-lmfit