Measured data often follows a known mathematical shape while still carrying noise from sampling, sensors, or simulation. SciPy provides scipy.optimize.curve_fit() for estimating the unknown parameters of that shape, such as an amplitude, decay rate, or baseline value.
The curve_fit() function expects a model callable whose first argument is the independent variable and whose remaining arguments are the fitted parameters. It returns optimized parameter values and an approximate covariance matrix, so one run can report fitted values, parameter standard errors, residual size, and an uncertainty sanity check.
A small exponential-decay data set keeps the fit easy to judge without turning the task into a plotting or data-cleaning workflow. Keep real input arrays as floating-point data, choose starting values on the same scale as the expected parameters, and review residuals before using the fit in later analysis.
import numpy as np from scipy.optimize import curve_fit def decay_model(x, amplitude, decay, baseline): return amplitude * np.exp(-decay * x) + baseline x = np.linspace(0.0, 4.0, 9) y = np.array([2.91, 1.77, 1.15, 0.82, 0.62, 0.51, 0.44, 0.41, 0.39]) initial_guess = (2.5, 1.0, 0.3) bounds = (0.0, [5.0, 5.0, 2.0]) params, covariance = curve_fit( decay_model, x, y, p0=initial_guess, bounds=bounds, ) stderr = np.sqrt(np.diag(covariance)) fit = decay_model(x, *params) residuals = y - fit rmse = np.sqrt(np.mean(residuals**2)) condition_number = np.linalg.cond(covariance) print(f"parameters: amplitude={params[0]:.3f}, decay={params[1]:.3f}, baseline={params[2]:.3f}") print(f"std_error: amplitude={stderr[0]:.3f}, decay={stderr[1]:.3f}, baseline={stderr[2]:.3f}") print(f"rmse: {rmse:.3f}") print(f"covariance_condition: {condition_number:.1f}")
p0 supplies the starting parameter values. The bounds setting keeps the fitted amplitude, decay rate, and baseline positive for this decay model.
$ python fit_curve.py parameters: amplitude=2.534, decay=1.174, baseline=0.371 std_error: amplitude=0.009, decay=0.011, baseline=0.006 rmse: 0.007 covariance_condition: 19.9
The fitted parameters are returned in the same order as the model function parameters after x.
The diagonal of the covariance matrix gives approximate parameter variances. Taking the square root produces one-standard-deviation errors when the model is well behaved near the optimum.
An rmse of 0.007 is small against response values that range from about 0.39 to 2.91, so the fitted curve follows this sample data closely.
A very large covariance_condition can indicate redundant parameters, mismatched parameter scales, or unstable uncertainty estimates. Simplify the model, rescale parameters, or choose better starting values before trusting the standard errors.