Source code for plotnine_extra.stats.stat_friedman_test
from __future__ import annotations
from typing import TYPE_CHECKING
from plotnine.doctools import document
from ._base_stat_test import _base_stat_test
if TYPE_CHECKING:
import numpy as np
import pandas as pd
[docs]
@document
class stat_friedman_test(_base_stat_test):
"""
Add Friedman test p-values to a plot
Performs the Friedman test, a non-parametric test for
repeated measures (alternative to repeated-measures
ANOVA), and displays the result as a text annotation.
{usage}
Parameters
----------
{common_parameters}
wid : str, default=None
Column name identifying subjects/individuals.
Required for reshaping the data into the wide
format needed by the Friedman test.
label_x_npc : float or str, default="center"
Normalized x position for the label.
label_y_npc : float or str, default="top"
Normalized y position for the label.
p_digits : int, default=3
Number of digits for p-value formatting.
See Also
--------
plotnine.geom_text : The default `geom` for this `stat`.
"""
_aesthetics_doc = """
{aesthetics_table}
**Options for computed aesthetics**
```python
"label" # Formatted test result label
"p" # P-value
"p_signif" # Significance symbol
"statistic" # Test statistic (chi-squared)
"df" # Degrees of freedom
"method" # Name of the test
```
"""
DEFAULT_PARAMS = {
"geom": "text",
"position": "identity",
"na_rm": False,
"wid": None,
"label_x_npc": "center",
"label_y_npc": "top",
"p_digits": 3,
}
CREATES = {
"label", "p", "p_signif", "statistic", "df", "method",
}
_test_method = "friedman.test"
_min_groups = 3
def _extract_groups(
self,
data: pd.DataFrame,
) -> list[np.ndarray]:
"""
Extract groups, using *wid* for subject alignment
when available.
"""
wid = self.params.get("wid")
if wid and wid in data.columns:
groups = []
for _, grp in data.groupby("x"):
sorted_vals = (
grp.sort_values(wid)["y"]
.to_numpy(dtype=float)
)
groups.append(sorted_vals)
else:
groups = [
grp["y"].to_numpy(dtype=float)
for _, grp in data.groupby("x")
]
# Ensure equal group sizes for Friedman test
if groups:
min_len = min(len(g) for g in groups)
groups = [g[:min_len] for g in groups]
return groups