xarray.DataArray.curvefit (original) (raw)

DataArray.curvefit(coords, func, reduce_dims=None, skipna=True, p0=None, bounds=None, param_names=None, errors='raise', kwargs=None)[source]#

Curve fitting optimization for arbitrary functions.

Wraps scipy.optimize.curve_fit with apply_ufunc.

Parameters:

Returns:

curvefit_results (Dataset) – A single dataset which contains:

[var]_curvefit_coefficients

The coefficients of the best fit.

[var]_curvefit_covariance

The covariance matrix of the coefficient estimates.

Examples

Generate some exponentially decaying data, where the decay constant and amplitude are different for different values of the coordinate x:

rng = np.random.default_rng(seed=0) def exp_decay(t, time_constant, amplitude): ... return np.exp(-t / time_constant) * amplitude ... t = np.arange(11) da = xr.DataArray( ... np.stack( ... [ ... exp_decay(t, 1, 0.1), ... exp_decay(t, 2, 0.2), ... exp_decay(t, 3, 0.3), ... ] ... ) ... + rng.normal(size=(3, t.size)) * 0.01, ... coords={"x": [0, 1, 2], "time": t}, ... ) da <xarray.DataArray (x: 3, time: 11)> Size: 264B array([[ 0.1012573 , 0.0354669 , 0.01993775, 0.00602771, -0.00352513, 0.00428975, 0.01328788, 0.009562 , -0.00700381, -0.01264187, -0.0062282 ], [ 0.20041326, 0.09805582, 0.07138797, 0.03216692, 0.01974438, 0.01097441, 0.00679441, 0.01015578, 0.01408826, 0.00093645, 0.01501222], [ 0.29334805, 0.21847449, 0.16305984, 0.11130396, 0.07164415, 0.04744543, 0.03602333, 0.03129354, 0.01074885, 0.01284436, 0.00910995]]) Coordinates:

Fit the exponential decay function to the data along the time dimension:

fit_result = da.curvefit("time", exp_decay) fit_result["curvefit_coefficients"].sel( ... param="time_constant" ... )
<xarray.DataArray 'curvefit_coefficients' (x: 3)> Size: 24B array([1.05692036, 1.73549638, 2.94215771]) Coordinates:

An initial guess can also be given with the p0 arg (although it does not make much of a difference in this simple example). To have a different guess for different coordinate points, the guess can be a DataArray. Here we use the same initial guess for the amplitude but different guesses for the time constant:

fit_result = da.curvefit( ... "time", ... exp_decay, ... p0={ ... "amplitude": 0.2, ... "time_constant": xr.DataArray([1, 2, 3], coords=[da.x]), ... }, ... ) fit_result["curvefit_coefficients"].sel(param="time_constant") <xarray.DataArray 'curvefit_coefficients' (x: 3)> Size: 24B array([1.0569213 , 1.73550052, 2.94215733]) Coordinates: