Pingouin is an open-source statistical package for Python that provides simple, readable functions for common statistical tests. It’s designed to be user-friendly while maintaining statistical rigor.
Why Pingouin?
- Readable Output: Results returned as pandas DataFrames
- Effect Sizes: Automatically calculates effect sizes
- Simple API: Consistent, intuitive function names
- Comprehensive: Covers most common statistical tests
- Well-Documented: Clear examples and explanations
Basic T-Tests
Independent Samples T-Test
import pingouin as pg
import pandas as pd
# Independent t-test
result = pg.ttest(
control_group['reaction_time'],
treatment_group['reaction_time'],
correction='auto' # Welch's t-test if unequal variances
)
print(result)
# Returns DataFrame with: T, dof, alternative, p-val, CI95%, cohen-d, BF10, power
Paired T-Test
# Paired samples (e.g., pre/post measurements)
result = pg.ttest(
df['pre_score'],
df['post_score'],
paired=True
)
One-Sample T-Test
# Test against a value (e.g., chance level)
result = pg.ttest(df['accuracy'], 0.5) # Test if accuracy > 50%
ANOVA
One-Way ANOVA
# One-way ANOVA
aov = pg.anova(
data=df,
dv='reaction_time', # Dependent variable
between='condition' # Independent variable
)
print(aov)
# Returns: Source, SS, DF, MS, F, p-unc, np2 (effect size)
Repeated Measures ANOVA
# Within-subjects ANOVA
aov = pg.rm_anova(
data=df,
dv='performance',
within='time_point',
subject='subject_id'
)
Two-Way ANOVA
# Two factors
aov = pg.anova(
data=df,
dv='score',
between=['treatment', 'gender']
)
Mixed ANOVA
# Mixed design (between + within factors)
aov = pg.mixed_anova(
data=df,
dv='response',
within='session',
subject='subject_id',
between='group'
)
Post-Hoc Tests
Pairwise Comparisons
# Post-hoc pairwise tests with multiple comparison correction
posthoc = pg.pairwise_tests(
data=df,
dv='score',
between='condition',
padjust='fdr_bh' # Benjamini-Hochberg FDR correction
)
print(posthoc)
# Shows all pairwise comparisons with corrected p-values
Tukey HSD
# Tukey's Honestly Significant Difference
tukey = pg.pairwise_tukey(
data=df,
dv='reaction_time',
between='condition'
)
Correlation Analysis
Pearson Correlation
# Pearson correlation
r = pg.corr(df['variable1'], df['variable2'])
print(r)
# Returns: n, r, CI95%, p-val, BF10, power
Spearman Correlation
# Non-parametric correlation
rho = pg.corr(df['var1'], df['var2'], method='spearman')
Partial Correlation
# Control for confounding variable
partial = pg.partial_corr(
data=df,
x='brain_activity',
y='behavior',
covar='age' # Control for age
)
Correlation Matrix
# Pairwise correlations for multiple variables
corr_matrix = pg.pairwise_corr(
df[['var1', 'var2', 'var3', 'var4']],
method='pearson'
)
Effect Sizes
Cohen’s d
# Effect size for t-test
d = pg.compute_effsize(
control_data,
treatment_data,
eftype='cohen'
)
# Or use hedges (corrected for small samples)
hedges_g = pg.compute_effsize(
control_data,
treatment_data,
eftype='hedges'
)
Confidence Intervals
# Bootstrap confidence interval
ci = pg.compute_bootci(
data,
func=np.mean,
n_boot=5000,
confidence=0.95
)
Normality and Assumptions
Test Normality
# Shapiro-Wilk test
normal, pval = pg.normality(df, dv='reaction_time', group='condition')
Test Homoscedasticity
# Levene's test for equal variances
equal_var, pval = pg.homoscedasticity(df, dv='score', group='condition')
Sphericity Test
# Mauchly's test for repeated measures
spher, W, chi2, dof, pval = pg.sphericity(
data=df,
dv='response',
subject='subject_id',
within='time'
)
Non-Parametric Tests
Mann-Whitney U Test
# Non-parametric alternative to t-test
result = pg.mwu(group1_data, group2_data)
Wilcoxon Signed-Rank Test
# Non-parametric paired test
result = pg.wilcoxon(pre_data, post_data)
Kruskal-Wallis Test
# Non-parametric alternative to ANOVA
result = pg.kruskal(
data=df,
dv='score',
between='condition'
)
Practical Neuroscience Examples
Calcium Imaging Analysis
import pingouin as pg
# Compare neural responses between conditions
aov = pg.anova(
data=neural_df,
dv='dF_F',
between='stimulus_type'
)
# Post-hoc comparisons
posthoc = pg.pairwise_tests(
data=neural_df,
dv='dF_F',
between='stimulus_type',
padjust='bonf'
)
# Effect sizes
effect_size = pg.compute_effsize(
neural_df[neural_df['stimulus'] == 'A']['dF_F'],
neural_df[neural_df['stimulus'] == 'B']['dF_F'],
eftype='cohen'
)
Behavioral Experiment Analysis
# Repeated measures ANOVA for learning over sessions
learning_aov = pg.rm_anova(
data=behavior_df,
dv='accuracy',
within='session',
subject='subject_id'
)
# Correlation between behavior and neural activity
correlation = pg.corr(
behavior_df['reaction_time'],
neural_df['peak_response']
)
Multi-Condition Comparison
# Compare firing rates across multiple brain regions
regions_aov = pg.anova(
data=ephys_df,
dv='firing_rate',
between='region'
)
# Pairwise comparisons with FDR correction
pairwise = pg.pairwise_tests(
data=ephys_df,
dv='firing_rate',
between='region',
padjust='fdr_bh'
)
# Check which comparisons are significant
significant = pairwise[pairwise['p-corr'] < 0.05]
Working with DataFrames
# Pingouin works seamlessly with pandas
df = pd.DataFrame({
'subject': [1, 1, 1, 2, 2, 2, 3, 3, 3],
'condition': ['A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C'],
'score': [10, 12, 14, 11, 13, 15, 9, 11, 13]
})
# Run analysis
result = pg.rm_anova(
data=df,
dv='score',
within='condition',
subject='subject'
)
# Results are pandas DataFrames - easy to save or process
result.to_csv('anova_results.csv')
Bayesian Statistics
# Bayesian t-test
result = pg.ttest(control, treatment, correction=False)
# Result includes BF10 (Bayes Factor)
# Interpret Bayes Factor
if result['BF10'].values[0] > 3:
print("Moderate evidence for alternative hypothesis")
elif result['BF10'].values[0] < 1/3:
print("Moderate evidence for null hypothesis")
Power Analysis
# Compute statistical power
power = pg.power_ttest(
d=0.5, # Effect size
n=30, # Sample size
alpha=0.05
)
# Or determine required sample size
n = pg.power_ttest(
d=0.5,
power=0.8,
alpha=0.05
)
Installation
pixi add pingouin
# or
conda install -c conda-forge pingouin
# or
pip install pingouin
Best Practices
- Always check assumptions (normality, homoscedasticity) before parametric tests
- Use FDR correction for multiple comparisons
- Report effect sizes along with p-values
- Consider Bayesian alternatives (BF10) for ambiguous results
- Visualize data before running statistical tests
- Save results as CSV for reproducibility
- Use paired tests when data is related (pre/post, matched subjects)
- Check power analysis for adequate sample sizes