Statistics¶
fdatools.stats: covariance and correlation of functional data, functional
depth, the functional boxplot, and permutation t and F tests.
f_test takes either raw regression inputs, f_test(y, x, basis=, lam=,
penalty=) like R's Fperm.fd, or a model fitted by
fregress, f_test(model, n_perm=1000), which refits that
exact model (its terms, intercept included, coefficient settings and weights)
under every permutation.
Functional statistics: covariance, correlation, depth, boxplots, tests and bands.
Replaces R's var.fd, cor.fd, fbplot, fdepth, tperm.fd,
Fperm.fd, the pointwise-variance use of y2cMap/fRegress.stderr,
plotbeta, plotscores and cycleplot.fd.
- :func:
covand :func:corgive the (cross-)covariance surface and the correlation matrix of one or two sets of curves. - :func:
depthorders curves from the centre outwards (modified band depth, band depth or Fraiman--Muniz depth) and returns the deepest curve and a trimmed mean; :func:boxplotbuilds the functional boxplot of Sun and Genton (2011) on top of it. - :func:
t_testand :func:f_testare permutation tests whose statistic is the largest pointwise two-sample t or regression F statistic. - :func:
confidence_bandgives pointwise confidence limits of a smooth or of regression coefficients; :func:plot_betadraws the latter. - :func:
cycleplotand :func:plot_scoresdraw bivariate cycles and principal component score scatters.
Depths and tests work on curve values sampled on a grid, so they return NumPy
arrays whatever the input namespace; :func:cov and :func:cor stay in the
namespace of their inputs.
Examples:
>>> import numpy as np
>>> from fdatools import BSpline, FData
>>> from fdatools.stats import depth
>>> fd = FData(np.random.default_rng(0).normal(size=(6, 9)), BSpline(n_basis=6))
>>> depth(fd).depth.shape
(9,)
DepthResult
dataclass
¶
DepthResult(
depth: NDArray,
median_index: int,
median: NDArray,
trimmed_index: NDArray,
trimmed_mean: NDArray,
t: NDArray | None,
)
Depth of every curve, with the deepest curve and a trimmed mean.
Attributes:
| Name | Type | Description |
|---|---|---|
depth |
ndarray
|
Depth of each curve, shape |
median_index |
int
|
Position of the deepest curve (the first one if several tie). |
median |
ndarray
|
Values of the deepest curve at the evaluation points. |
trimmed_index |
ndarray
|
Positions, in increasing order, of the curves whose depth is at least
the |
trimmed_mean |
ndarray
|
Pointwise mean of the curves in |
t |
ndarray or None
|
The evaluation points, or |
Examples:
>>> import numpy as np
>>> from fdatools.stats import depth
>>> values = np.array([[0.0, 1.0, 2.0], [0.0, 1.0, 2.0]])
>>> depth(values).median_index
1
BoxplotResult
dataclass
¶
BoxplotResult(
values: NDArray,
t: NDArray | None,
depth: NDArray,
median_index: int,
median: NDArray,
outliers: NDArray,
central_lower: NDArray,
central_upper: NDArray,
fence_lower: NDArray,
fence_upper: NDArray,
whisker_lower: NDArray,
whisker_upper: NDArray,
)
A functional boxplot: depth ordering, central region, fences and outliers.
Attributes:
| Name | Type | Description |
|---|---|---|
values |
ndarray
|
The curves as sampled, shape |
t |
ndarray or None
|
The evaluation points, or |
depth |
ndarray
|
Depth of each curve, shape |
median_index |
int
|
Position of the deepest curve. |
median |
ndarray
|
Values of the deepest curve. |
outliers |
ndarray
|
Positions of the curves leaving the fences at some point, increasing. |
central_lower, central_upper |
ndarray
|
Pointwise envelope of the central region, the |
fence_lower, fence_upper |
ndarray
|
The box inflated by |
whisker_lower, whisker_upper |
ndarray
|
Pointwise envelope of every curve that is not an outlier. |
Examples:
>>> import numpy as np
>>> from fdatools.stats import boxplot
>>> values = np.vstack([np.arange(7.0), np.arange(7.0)])
>>> values[:, 6] = 40.0
>>> boxplot(values).outliers.tolist()
[6]
plot ¶
plot(ax: Axes | None = None, **kwargs: Any) -> Axes
Draw the boxplot: central region, median, whiskers and outliers.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ax
|
Axes
|
Axes to draw on. A new figure is created when omitted. |
None
|
**kwargs
|
Any
|
Passed to :meth: |
{}
|
Returns:
| Type | Description |
|---|---|
Axes
|
The axes drawn on. The median is the first line, then the upper and lower whiskers, then one line per outlier; the central region is the single filled collection. |
Examples:
>>> import matplotlib
>>> matplotlib.use("Agg")
>>> import numpy as np
>>> from fdatools.stats import boxplot
>>> values = np.vstack([np.arange(7.0), np.arange(7.0) + 1.0])
>>> len(boxplot(values).plot().lines)
3
PermutationTestResult
dataclass
¶
PermutationTestResult(
statistic: float,
null: NDArray,
pvalue: float,
critical_value: float,
pointwise: NDArray,
pointwise_null: NDArray,
pointwise_pvalue: NDArray,
pointwise_critical_value: NDArray,
t: NDArray | None,
)
Outcome of a permutation test built on a pointwise statistic.
Attributes:
| Name | Type | Description |
|---|---|---|
statistic |
float
|
The observed statistic: the maximum of |
null |
ndarray
|
The statistic recomputed under each permutation, shape |
pvalue |
float
|
Share of permutations whose statistic reaches the observed one. |
critical_value |
float
|
The |
pointwise |
ndarray
|
Observed statistic at each evaluation point, shape |
pointwise_null |
ndarray
|
Pointwise statistic under each permutation, |
pointwise_pvalue |
ndarray
|
Pointwise permutation p-values. |
pointwise_critical_value |
ndarray
|
Pointwise |
t |
ndarray or None
|
The evaluation points; |
Examples:
>>> import numpy as np
>>> from fdatools import BSpline, FData
>>> from fdatools.stats import t_test
>>> rng = np.random.default_rng(0)
>>> a = FData(rng.normal(size=(5, 6)), BSpline(n_basis=5))
>>> b = FData(rng.normal(size=(5, 6)) + 3.0, BSpline(n_basis=5))
>>> t_test(a, b, n_perm=50, random_state=1).pvalue
0.0
ConfidenceBand
dataclass
¶
ConfidenceBand(
t: Array,
estimate: Array,
stderr: Array,
lower: Array,
upper: Array,
level: float,
name: str | None = None,
)
Pointwise confidence band of a smooth or of a regression coefficient.
Attributes:
| Name | Type | Description |
|---|---|---|
t |
array
|
Evaluation points, shape |
estimate |
array
|
The estimate at |
stderr |
array
|
Pointwise standard error, shape |
lower, upper |
array
|
|
level |
float
|
Pointwise coverage of the band. |
name |
str or None
|
Term name for a regression coefficient, |
Examples:
>>> import numpy as np
>>> from fdatools import BSpline
>>> from fdatools.smoothing import smooth
>>> from fdatools.stats import confidence_band
>>> t = np.linspace(0.0, 1.0, 40)
>>> fit = smooth(np.sin(6.0 * t), t, basis=BSpline(n_basis=8), lam=1e-6)
>>> band = confidence_band(fit, np.array([0.25, 0.5]), sigma_e=0.01)
>>> band.stderr.shape, band.lower.shape
((2,), (2, 1))
plot ¶
plot(ax: Axes | None = None, **kwargs: Any) -> Axes
Draw the estimate with its lower and upper limits.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ax
|
Axes
|
Axes to draw on. A new figure is created when omitted. |
None
|
**kwargs
|
Any
|
Passed to :meth: |
{}
|
Returns:
| Type | Description |
|---|---|
Axes
|
The axes drawn on. The estimate lines come first, then the lower and the upper limits (dashed); a dotted zero line is added last when the band crosses zero. |
Examples:
>>> import matplotlib
>>> matplotlib.use("Agg")
>>> import numpy as np
>>> from fdatools.stats import ConfidenceBand
>>> t = np.linspace(0.0, 1.0, 5)
>>> band = ConfidenceBand(t, t, 0.1 + 0 * t, t - 0.2, t + 0.2, 0.95)
>>> len(band.plot().lines)
4
cov ¶
cov(x: FData, y: FData | None = None) -> BiFData
Return the sample (cross-)covariance surface.
Replaces R's var.fd. With one argument this is :meth:FData.cov. With
two, it is the bivariate function
c(s, t) = 1 / (n - 1) sum_i (x_i(s) - xbar(s)) (y_i(t) - ybar(t))
expanded in x.basis along s and y.basis along t. Both are
exact: centring and the outer product act on the coefficients.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
FData
|
First set of curves. |
required |
y
|
FData
|
Second set of curves, paired with |
None
|
Returns:
| Type | Description |
|---|---|
BiFData
|
The covariance surface. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If fewer than two curves are given, or |
Examples:
>>> import numpy as np
>>> from fdatools import BSpline, FData
>>> from fdatools.stats import cov
>>> rng = np.random.default_rng(0)
>>> x = FData(rng.normal(size=(5, 8)), BSpline(n_basis=5))
>>> y = FData(rng.normal(size=(4, 8)), BSpline(n_basis=4))
>>> cov(x, y).coefs.shape
(5, 4)
cor ¶
cor(
x: FData,
y: FData | None = None,
*,
s: Any = None,
t: Any = None,
) -> Array
Return the sample correlation of x(s) with y(t) on a grid.
Replaces R's cor.fd. Entry [a, b] is the correlation, across
curves, of x(s[a]) and y(t[b]); with y omitted it is the
autocorrelation of x. A correlation is a ratio of covariances, not a
basis expansion, so it is returned as values rather than as a
:class:~fdatools.core.BiFData.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
FData
|
First set of curves. |
required |
y
|
FData
|
Second set of curves, paired with |
None
|
s
|
array_like
|
Evaluation points for |
None
|
t
|
array_like
|
Evaluation points for |
None
|
Returns:
| Type | Description |
|---|---|
array
|
Shape |
Raises:
| Type | Description |
|---|---|
ValueError
|
If fewer than two curves are given, or |
Examples:
>>> import numpy as np
>>> from fdatools import BSpline, FData
>>> from fdatools.stats import cor
>>> fd = FData(np.random.default_rng(0).normal(size=(5, 8)), BSpline(n_basis=5))
>>> grid = np.linspace(0.0, 1.0, 3)
>>> np.round(np.diag(cor(fd, s=grid, t=grid)), 12).tolist()
[1.0, 1.0, 1.0]
depth ¶
depth(
data: FData | Any,
*,
method: str = "MBD",
t: Any = None,
trim: float = 0.25,
) -> DepthResult
Rank curves from the centre outwards by a functional depth.
Replaces R's fdepth (type = "FM") and the depth half of fbplot.
With r_i(t) the rank of x_i(t) among the n values at t
(average ranks for ties):
"MBD"-- modified band depth (Lopez-Pintado and Romo, 2009): the share of bands spanned by pairs of curves that containx_i(t), averaged over the points,mean_t [(r - 1)(n - r) + n - 1] / C(n, 2)."BD2"-- the rank-based two-curve band depth of Sun, Genton and Nychka (2012),[(n - max_t r)(min_t r - 1) + n - 1] / C(n, 2). It equals the share of bands containing the whole curve when the curves do not cross, and is what R'sfbplot(method = "BD2")reports."both"-- band depth rounded to four decimals, ties broken by modified band depth (round(1e4 BD2) + MBD), asfbplot(method = "Both")."FM"-- Fraiman and Muniz (2001) depth,mean_t [1 - |1/2 - F_n(x_i(t))|]withF_nthe empirical distribution function att.
Averages over t weight every evaluation point equally.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
FData or array_like
|
Curves, or their values as an |
required |
method
|
('MBD', 'BD2', 'both', 'FM')
|
Depth notion, case-insensitive. Defaults to |
"MBD"
|
t
|
array_like
|
Evaluation points. For :class: |
None
|
trim
|
float
|
Share of least deep curves left out of the trimmed mean: curves whose
depth reaches the |
0.25
|
Returns:
| Type | Description |
|---|---|
DepthResult
|
Depths, the deepest curve and the trimmed mean. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Examples:
>>> import numpy as np
>>> from fdatools.stats import depth
>>> values = np.array([[0.0, 1.0, 2.0, 3.0], [0.0, 1.0, 2.0, 3.0]])
>>> depth(values, method="FM").depth.tolist()
[0.75, 1.0, 0.75, 0.5]
boxplot ¶
boxplot(
data: FData | Any,
*,
method: str = "MBD",
t: Any = None,
prob: float = 0.5,
factor: float = 1.5,
) -> BoxplotResult
Build the functional boxplot of Sun and Genton (2011).
Replaces R's fbplot and boxplot.fd. Curves are ordered by
:func:depth. The central region is the pointwise envelope of the
ceil(prob * n_curves) deepest curves; inflating it by factor times
its height on both sides gives the fences, and a curve that leaves the
fences anywhere is an outlier. The whiskers are the envelope of the curves
that are not outliers.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
FData or array_like
|
Curves, or their values as an |
required |
method
|
('MBD', 'BD2', 'both', 'FM')
|
Depth used to order the curves. Defaults to |
"MBD"
|
t
|
array_like
|
Evaluation points, as for :func: |
None
|
prob
|
float
|
Share of curves in the central region. Default |
0.5
|
factor
|
float
|
Fence inflation factor. Default |
1.5
|
Returns:
| Type | Description |
|---|---|
BoxplotResult
|
Depths, median, envelopes and outliers; call |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Examples:
>>> import numpy as np
>>> from fdatools.stats import boxplot
>>> rng = np.random.default_rng(1)
>>> values = rng.normal(size=(20, 15))
>>> values[:, 4] += 25.0
>>> boxplot(values).outliers.tolist()
[4]
t_test ¶
t_test(
x1: FData,
x2: FData,
*,
n_perm: int = 200,
q: float = 0.05,
t: Any = None,
random_state: RandomState = None,
) -> PermutationTestResult
Permutation test for a difference between two groups of curves.
Replaces R's tperm.fd. The pointwise statistic is Welch's
T(t) = |xbar_1(t) - xbar_2(t)| / sqrt(s_1^2(t) / n_1 + s_2^2(t) / n_2)
and the test statistic is its maximum over the evaluation points. Its null
distribution is obtained by pooling the curves, drawing a random
permutation, and assigning the first n_1 to the first group.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x1
|
FData
|
The two groups, each with at least two curves, on one domain. |
required |
x2
|
FData
|
The two groups, each with at least two curves, on one domain. |
required |
n_perm
|
int
|
Number of permutations. Default |
200
|
q
|
float
|
Upper-tail probability for the critical value: |
0.05
|
t
|
array_like
|
Evaluation points; 101 equally spaced points over the domain by default. |
None
|
random_state
|
(int, Generator or None)
|
Seed or generator for the permutations; each one is drawn with the
generator's |
None
|
Returns:
| Type | Description |
|---|---|
PermutationTestResult
|
Observed statistic, null distribution, p-value and pointwise detail. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If a group has fewer than two curves, the groups differ in domain or
carry several variables, or |
TypeError
|
If |
Examples:
>>> import numpy as np
>>> from fdatools import BSpline, FData
>>> from fdatools.stats import t_test
>>> rng = np.random.default_rng(0)
>>> a = FData(rng.normal(size=(5, 8)), BSpline(n_basis=5))
>>> b = FData(rng.normal(size=(5, 7)), BSpline(n_basis=5))
>>> result = t_test(a, b, n_perm=100, random_state=0)
>>> 0.0 <= result.pvalue <= 1.0
True
f_test ¶
f_test(
y: FRegressResult,
x: None = None,
*,
n_perm: int = 200,
q: float = 0.05,
t: Any = None,
random_state: RandomState = None,
) -> PermutationTestResult
f_test(
y: FData | Any,
x: Any,
*,
basis: Basis | Sequence[Basis | None] | None = None,
lam: float | Sequence[float] = 0.0,
penalty: int | LDO | Sequence[int | LDO] = 2,
n_perm: int = 200,
q: float = 0.05,
t: Any = None,
random_state: RandomState = None,
) -> PermutationTestResult
f_test(
y: FRegressResult | FData | Any,
x: Any = None,
*,
basis: Basis | Sequence[Basis | None] | None = None,
lam: float | Sequence[float] | None = None,
penalty: int | LDO | Sequence[int | LDO] | None = None,
n_perm: int = 200,
q: float = 0.05,
t: Any = None,
random_state: RandomState = None,
) -> PermutationTestResult
Permutation F test of no effect in a functional linear regression.
Replaces R's Fperm.fd. The regression is fitted by penalised least
squares, then
F(t) = var_i(yhat_i(t)) / mean_i((y_i(t) - yhat_i(t))^2)
(the variance with denominator n - 1) is evaluated pointwise and the
test statistic is its maximum. The null distribution refits the model
after randomly permuting the responses against fixed covariates.
The model comes either from raw inputs, as in R's
Fperm.fd(yfdPar, xfdlist, betalist), or from a model fitted by
:func:fdatools.regression.fregress (f_test(model)). In the raw form no
intercept is added: include a vector of ones in x for one, as in R. In
the model form the test refits exactly the fitted model -- its response,
terms (an intercept included), coefficient bases, smoothing parameters,
penalty operators and observation weights -- so x, basis, lam
and penalty must not be given. Weights enter the fit only (a weighted
least-squares refit under every permutation, the weights staying with the
covariates); F itself is unweighted.
Two models are supported:
- functional response (:class:
FData): the concurrent modely_i(t) = sum_j x_ij(t) beta_j(t), where a scalar covariate is constant int, everybeta_jis a curve inbasis[j](defaulty.basis) and the penalty islam[j] * int (L_j beta_j)^2; - scalar response (1-D array):
y_i = sum_j int x_ij(t) beta_j(t) dtfor functional covariates (beta_jinbasis[j], default the covariate's basis) plus ordinary coefficients for scalar covariates, whosebasis,lamandpenaltyentries are ignored.Fis then a single number.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
y
|
(FData, array_like or FRegressResult)
|
Response: |
required |
x
|
array_like, FData or sequence of them
|
Covariates, each a length- |
None
|
basis
|
Basis or list of Basis
|
Basis of each coefficient function: one shared value, or a list (or
tuple) with one entry per covariate, |
None
|
lam
|
float or list of float
|
Smoothing parameter of each coefficient function, shared or one per
covariate. Default |
None
|
penalty
|
int, LDO or list of them
|
Roughness operator of each coefficient function, shared or one per
covariate. Default |
None
|
n_perm
|
int
|
Number of permutations. Default |
200
|
q
|
float
|
Upper-tail probability: |
0.05
|
t
|
array_like
|
Evaluation points for a functional response; 101 equally spaced points over the domain by default. |
None
|
random_state
|
(int, Generator or None)
|
Seed or generator; each permutation is |
None
|
Returns:
| Type | Description |
|---|---|
PermutationTestResult
|
Observed statistic, null distribution, p-value and pointwise detail
( |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the covariates, bases or settings do not match the response, the
normal equations are singular, or |
TypeError
|
If |
Notes
Weights differ from R. f_test(model) on a model fitted with
fregress(..., weights=w) refits it by weighted least squares under
every permutation, so the statistic and the null distribution change with
the weights (unit weights give the unweighted test). R's
Fperm.fd(..., wt = w) accepts weights but returns the same Fobs and
null distribution as with no weights at all. To reproduce an R
Fperm.fd result, test a model fitted without weights. The raw form
f_test(y, x, ...) has no weights and matches R.
Examples:
>>> import numpy as np
>>> from fdatools import FData, Fourier
>>> from fdatools.stats import f_test
>>> rng = np.random.default_rng(0)
>>> group = np.repeat([0.0, 1.0], 6)
>>> y = FData(rng.normal(size=(5, 12)) + 2.0 * group, Fourier(n_basis=5))
>>> result = f_test(y, [np.ones(12), group], lam=1e-4, n_perm=50, random_state=0)
>>> result.pvalue < 0.05
True
The same test on a fitted model, whose intercept term is part of the model:
>>> from fdatools.regression import fregress
>>> model = fregress(y, {"const": 1.0, "group": group}, lam=1e-4)
>>> again = f_test(model, n_perm=50, random_state=0)
>>> again.statistic == result.statistic
True
confidence_band ¶
confidence_band(
fit: SmoothResult,
t: Any = None,
*,
sigma_e: Any = None,
level: float = 0.95,
deriv: int = 0,
y2c_map: Any = None,
) -> ConfidenceBand
confidence_band(
fit: FRegressResult,
t: Any = None,
*,
sigma_e: Any = None,
level: float = 0.95,
deriv: int = 0,
y2c_map: Any = None,
) -> tuple[ConfidenceBand, ...]
confidence_band(
fit: SmoothResult | FRegressResult,
t: Any = None,
*,
sigma_e: Any = None,
level: float = 0.95,
deriv: int = 0,
y2c_map: Any = None,
) -> ConfidenceBand | tuple[ConfidenceBand, ...]
Pointwise confidence band of a smooth or of regression coefficients.
Replaces the variance computations R users build from smooth.basis's
y2cMap and from fRegress.stderr (Ramsay, Hooker and Graves, 2009,
sections 5.5 and 9.4). Both fits are linear in the data, so the
covariance of their coefficients follows from the error covariance Σ:
- a smooth has coefficients
c = S y(Sitsy2c_map) andVar x(t) = φ(t)ᵀ S Σ Sᵀ φ(t), withφthe basis (or itsderiv-th derivative); - a regression has coefficient covariance
Vfrom :meth:~fdatools.regression.FRegressResult.stderrandVar β_j(t) = θ_j(t)ᵀ V_jj θ_j(t), withθ_jthe basis of thej-th coefficient.
The band is estimate ± z · stderr with z the (1 + level) / 2
normal quantile. It is pointwise: it covers the truth at each t with
probability level, not along the whole curve at once, and it ignores
the bias the roughness penalty introduces.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fit
|
SmoothResult or FRegressResult
|
A fit from :func: |
required |
t
|
array
|
Evaluation points. Default: 101 equally spaced points over the domain (of each coefficient, for a regression). |
None
|
sigma_e
|
float or array
|
Covariance |
None
|
level
|
float
|
Pointwise coverage, strictly between 0 and 1. Default |
0.95
|
deriv
|
int
|
Derivative order of the band. Default |
0
|
y2c_map
|
array
|
Regression only: data-to-coefficient map of the response smooth,
passed to :meth: |
None
|
Returns:
| Type | Description |
|---|---|
ConfidenceBand or tuple of ConfidenceBand
|
One band for a smooth; one band per term, in model order, for a regression. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
TypeError
|
If |
Examples:
>>> import numpy as np
>>> from fdatools.regression import fregress
>>> from fdatools.stats import confidence_band
>>> z = np.linspace(-1.0, 1.0, 30)
>>> model = fregress(1.0 + 2.0 * z + 0.1 * np.cos(9.0 * z), [1.0, z])
>>> const, slope = confidence_band(model)
>>> slope.name, bool(np.all(slope.lower < 2.0) and np.all(slope.upper > 2.0))
('x1', True)
plot_beta ¶
plot_beta(
fit: FRegressResult
| ConfidenceBand
| Sequence[ConfidenceBand],
t: Any = None,
*,
level: float = 0.95,
sigma_e: Any = None,
y2c_map: Any = None,
axes: Sequence[Axes] | None = None,
**kwargs: Any,
) -> list[Axes]
Plot regression coefficients with their pointwise confidence limits.
Replaces R's plotbeta: one panel per coefficient, the estimate as a
solid line, the limits dashed, and a dotted zero line when the band
crosses zero (R's zerofind).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fit
|
FRegressResult, ConfidenceBand or sequence of ConfidenceBand
|
A fitted regression (its bands are computed with
:func: |
required |
t
|
array
|
Evaluation points, used when |
None
|
level
|
float
|
Pointwise coverage, used when |
0.95
|
sigma_e
|
optional
|
Passed to :func: |
None
|
y2c_map
|
optional
|
Passed to :func: |
None
|
axes
|
sequence of matplotlib.axes.Axes
|
One axes per band. A new figure with stacked panels when omitted. |
None
|
**kwargs
|
Any
|
Passed to :meth: |
{}
|
Returns:
| Type | Description |
|---|---|
list of matplotlib.axes.Axes
|
The axes drawn on, one per band, each titled with its term name. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Examples:
>>> import matplotlib
>>> matplotlib.use("Agg")
>>> import numpy as np
>>> from fdatools.regression import fregress
>>> from fdatools.stats import plot_beta
>>> z = np.linspace(-1.0, 1.0, 30)
>>> model = fregress(z + 0.1 * np.cos(9.0 * z), [1.0, z])
>>> [ax.get_title() for ax in plot_beta(model)]
['x0', 'x1']
cycleplot ¶
cycleplot(
fd: FData,
y: FData | None = None,
*,
ax: Axes | None = None,
n_points: int = 201,
**kwargs: Any,
) -> Axes
Plot the cycles of a bivariate functional observation (R's cycleplot.fd).
Each curve traces (x(t), y(t)) over its domain, so a periodic pair --
hip against knee angle over a gait cycle, temperature against
precipitation over a year -- draws one closed loop per curve. To see the
cycles one at a time, pass fd[i].
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fd
|
FData
|
Curves with two variables, or the first coordinate when |
required |
y
|
FData
|
The second coordinate, with one variable and as many curves as |
None
|
ax
|
Axes
|
Axes to draw on. A new figure is created when omitted. |
None
|
n_points
|
int
|
Size of the evaluation grid over the domain. Default |
201
|
**kwargs
|
Any
|
Passed to :meth: |
{}
|
Returns:
| Type | Description |
|---|---|
Axes
|
The axes drawn on, with one line per curve. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the curves are not bivariate, |
Examples:
>>> import matplotlib
>>> matplotlib.use("Agg")
>>> import numpy as np
>>> from fdatools import FData, Fourier
>>> from fdatools.stats import cycleplot
>>> basis = Fourier(domain=(0.0, 1.0), n_basis=3)
>>> coefs = np.zeros((3, 2, 2))
>>> coefs[1, :, 0] = coefs[2, :, 1] = 1.0
>>> len(cycleplot(FData(coefs, basis)).lines)
2
plot_scores ¶
plot_scores(
scores: Any,
components: tuple[int, int] = (0, 1),
*,
ax: Axes | None = None,
labels: Sequence[Any] | None = None,
**kwargs: Any,
) -> Axes
Scatter two principal component scores against each other (R's plotscores).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
scores
|
FPCA or array
|
A fitted :class: |
required |
components
|
tuple of int
|
Zero-based indices of the two components. Default |
(0, 1)
|
ax
|
Axes
|
Axes to draw on. A new figure is created when omitted. |
None
|
labels
|
sequence
|
One label per curve, written next to its point. |
None
|
**kwargs
|
Any
|
Passed to :meth: |
{}
|
Returns:
| Type | Description |
|---|---|
Axes
|
The axes drawn on; the points are its single collection. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the scores are not a matrix, a component index is out of range, or
|
Examples:
>>> import matplotlib
>>> matplotlib.use("Agg")
>>> import numpy as np
>>> from fdatools.stats import plot_scores
>>> ax = plot_scores(np.array([[1.0, 2.0], [3.0, -1.0], [0.0, 0.5]]))
>>> ax.collections[0].get_offsets().shape
(3, 2)