AutoStatLib 0.4.4__tar.gz → 0.4.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. autostatlib-0.4.5/PKG-INFO +365 -0
  2. autostatlib-0.4.5/README.md +330 -0
  3. {autostatlib-0.4.4 → autostatlib-0.4.5}/requirements.txt +1 -1
  4. {autostatlib-0.4.4 → autostatlib-0.4.5}/src/AutoStatLib/StatPlots.py +7 -1
  5. {autostatlib-0.4.4 → autostatlib-0.4.5}/src/AutoStatLib/_version.py +1 -1
  6. autostatlib-0.4.5/src/AutoStatLib.egg-info/PKG-INFO +365 -0
  7. {autostatlib-0.4.4 → autostatlib-0.4.5}/src/AutoStatLib.egg-info/requires.txt +1 -1
  8. autostatlib-0.4.4/PKG-INFO +0 -193
  9. autostatlib-0.4.4/README.md +0 -158
  10. autostatlib-0.4.4/src/AutoStatLib.egg-info/PKG-INFO +0 -193
  11. {autostatlib-0.4.4 → autostatlib-0.4.5}/LICENSE +0 -0
  12. {autostatlib-0.4.4 → autostatlib-0.4.5}/MANIFEST.in +0 -0
  13. {autostatlib-0.4.4 → autostatlib-0.4.5}/pyproject.toml +0 -0
  14. {autostatlib-0.4.4 → autostatlib-0.4.5}/setup.cfg +0 -0
  15. {autostatlib-0.4.4 → autostatlib-0.4.5}/src/AutoStatLib/AutoStatLib.py +0 -0
  16. {autostatlib-0.4.4 → autostatlib-0.4.5}/src/AutoStatLib/__init__.py +0 -0
  17. {autostatlib-0.4.4 → autostatlib-0.4.5}/src/AutoStatLib/__main__.py +0 -0
  18. {autostatlib-0.4.4 → autostatlib-0.4.5}/src/AutoStatLib/_protocol.py +0 -0
  19. {autostatlib-0.4.4 → autostatlib-0.4.5}/src/AutoStatLib/helpers.py +0 -0
  20. {autostatlib-0.4.4 → autostatlib-0.4.5}/src/AutoStatLib/normality_tests.py +0 -0
  21. {autostatlib-0.4.4 → autostatlib-0.4.5}/src/AutoStatLib/statistical_tests.py +0 -0
  22. {autostatlib-0.4.4 → autostatlib-0.4.5}/src/AutoStatLib/text_formatting.py +0 -0
  23. {autostatlib-0.4.4 → autostatlib-0.4.5}/src/AutoStatLib.egg-info/SOURCES.txt +0 -0
  24. {autostatlib-0.4.4 → autostatlib-0.4.5}/src/AutoStatLib.egg-info/dependency_links.txt +0 -0
  25. {autostatlib-0.4.4 → autostatlib-0.4.5}/src/AutoStatLib.egg-info/top_level.txt +0 -0
  26. {autostatlib-0.4.4 → autostatlib-0.4.5}/tests/test_autostatlib.py +0 -0
  27. {autostatlib-0.4.4 → autostatlib-0.4.5}/tests/test_statplots.py +0 -0
@@ -0,0 +1,365 @@
1
+ Metadata-Version: 2.4
2
+ Name: AutoStatLib
3
+ Version: 0.4.5
4
+ Summary: AutoStatLib - a simple statistical analysis tool
5
+ Author: Stemonitis, SciWare LLC
6
+ Author-email: konung-yaropolk <yaropolk1995@gmail.com>
7
+ License-Expression: LGPL-2.1-or-later
8
+ Project-URL: Homepage, https://github.com/konung-yaropolk/AutoStatLib
9
+ Project-URL: Repository, https://github.com/konung-yaropolk/AutoStatLib.git
10
+ Project-URL: Issues, https://github.com/konung-yaropolk/AutoStatLib/issues
11
+ Keywords: Science,Statistics
12
+ Classifier: Programming Language :: Python
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Development Status :: 4 - Beta
17
+ Classifier: Intended Audience :: Developers
18
+ Classifier: Intended Audience :: Science/Research
19
+ Classifier: Natural Language :: English
20
+ Classifier: Topic :: Software Development :: Libraries
21
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
+ Classifier: Topic :: Scientific/Engineering
23
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
24
+ Requires-Python: >=3.10
25
+ Description-Content-Type: text/markdown
26
+ License-File: LICENSE
27
+ Requires-Dist: numpy
28
+ Requires-Dist: scipy>=1.17.0
29
+ Requires-Dist: statsmodels
30
+ Requires-Dist: matplotlib
31
+ Requires-Dist: seaborn
32
+ Requires-Dist: scikit-posthocs
33
+ Requires-Dist: pandas
34
+ Dynamic: license-file
35
+
36
+ # AutoStatLib - python library for automated statistical analysis
37
+
38
+ [![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/konung-yaropolk/AutoStatLib/tests.yml?label=Tests)](https://github.com/konung-yaropolk/AutoStatLib/actions/workflows/tests.yml)
39
+ [![pypi_version](https://img.shields.io/pypi/v/AutoStatLib?label=PyPI&color=green)](https://pypi.org/project/AutoStatLib)
40
+ [![GitHub Release](https://img.shields.io/github/v/release/konung-yaropolk/AutoStatLib?label=GitHub&color=green&link=https%3A%2F%2Fgithub.com%2Fkonung-yaropolk%2FAutoStatLib)](https://github.com/konung-yaropolk/AutoStatLib)
41
+ [![PyPI - License](https://img.shields.io/pypi/l/AutoStatLib)](https://pypi.org/project/AutoStatLib)
42
+ [![Python](https://img.shields.io/badge/Python-v3.10%5E-green?logo=python)](https://pypi.org/project/AutoStatLib)
43
+ [![PyPI - Downloads](https://img.shields.io/pypi/dm/AutoStatLib?label=PyPI%20stats&color=blue)](https://pypi.org/project/AutoStatLib)
44
+
45
+ AutoStatLib picks the right statistical test for your data and runs it — automatically, or manually if you prefer to choose. It checks normality, decides between parametric and non-parametric tests, accounts for paired vs. independent groups, and (optionally) runs post-hoc pairwise comparisons. Results come back as a plain Python dictionary, and a companion plotting module turns that same dictionary straight into a publication-style figure.
46
+
47
+ ## Table of contents
48
+
49
+ - [Install](#install)
50
+ - [Quick start](#quick-start)
51
+ - [How the API works](#how-the-api-works)
52
+ - [1. Creating an analysis](#1-creating-an-analysis)
53
+ - [2. Running a test](#2-running-a-test)
54
+ - [3. How automatic test selection works](#3-how-automatic-test-selection-works)
55
+ - [4. Reading the results](#4-reading-the-results)
56
+ - [5. Warnings](#5-warnings)
57
+ - [6. Text summary](#6-text-summary)
58
+ - [Plotting results](#plotting-results)
59
+
60
+
61
+ ---
62
+
63
+ ## Install
64
+
65
+ ```bash
66
+ pip install AutoStatLib
67
+ ```
68
+
69
+ Requires Python ≥ 3.10.
70
+
71
+ ---
72
+
73
+ ## Quick start
74
+
75
+ ```python
76
+ import numpy as np
77
+ import AutoStatLib
78
+
79
+ # two independent, normally-distributed groups
80
+ group_A = list(np.random.normal(loc=4.0, scale=1.0, size=30))
81
+ group_B = list(np.random.normal(loc=6.5, scale=2.0, size=30))
82
+
83
+ analysis = AutoStatLib.StatisticalAnalysis([group_A, group_B],
84
+ groups_name=['Control', 'Drug'],
85
+ paired=False,
86
+ verbose=False,
87
+ posthoc=True)
88
+
89
+ analysis.RunAuto()
90
+ result = analysis.GetResult()
91
+
92
+ print(f"{result['Test_Name']} \np-value: {result['p_value']} \nSignificance: {result['Significance(p<0.05)']}")
93
+
94
+ fig = AutoStatLib.StatPlots.BarStatPlot(result['Samples'], **result)
95
+ fig.plot()
96
+ fig.show()
97
+ fig.save('result.png')
98
+
99
+ ```
100
+
101
+ More runnable examples live in the [`/demo`](./demo) directory of this repo.
102
+
103
+ ---
104
+
105
+ ## How the API works
106
+
107
+ The library is built around one class, **`StatisticalAnalysis`**. You construct it with your data and configuration, call one of its `Run*()` methods to actually perform a test, then pull the outcome out with `GetResult()`.
108
+
109
+ ```
110
+ StatisticalAnalysis(data, ...) → .RunAuto() / .RunTtest() / ... → .GetResult()
111
+ → .GetSummary()
112
+ ```
113
+
114
+ ### 1. Creating an analysis
115
+
116
+ ```python
117
+ analysis = AutoStatLib.StatisticalAnalysis(
118
+ groups_list,
119
+ paired=False,
120
+ tails=2,
121
+ posthoc=True,
122
+ verbose=True,
123
+ raise_errors=False,
124
+ groups_name=None,
125
+ subgrouping=None,
126
+ )
127
+ ```
128
+
129
+ | Parameter | Type | Default | Description |
130
+ |---|---|---|---|
131
+ | `groups_list` | `list[list[float]]` | — | Your data: a list of groups, each group a list of numbers. 1 group → single-sample test, 2 groups → two-sample test, 3+ groups → multi-group test. Non-numeric values inside a group (strings, `None`, etc.) are silently dropped. Each group needs at least 4 valid values. |
132
+ | `paired` | `bool` | `False` | Set `True` if the groups are dependent / repeated-measures (e.g. before–after on the same subjects). Determines whether paired tests (t-test paired, Wilcoxon, repeated-measures ANOVA, Friedman) or independent tests are eligible. |
133
+ | `tails` | `int` (`1` or `2`) | `2` | One-tailed or two-tailed p-value. |
134
+ | `popmean` | `float \| None` | `None` | Population mean to compare against — only used for single-sample tests (`RunTtestSingleSample`, `RunWilcoxonSingleSample`). If left `None` for a single-sample test, AutoStatLib defaults to `0` and adds a warning to the result. |
135
+ | `posthoc` | `bool` | `False` | If `True` and you run a 3+ group test, a post-hoc pairwise comparison matrix is computed (Tukey's HSD after ANOVA, Dunn's test after Kruskal-Wallis). |
136
+ | `verbose` | `bool` | `True` | If `True`, a full human-readable analysis log (data table, normality results, chosen test, results table) is printed to stdout every time you run a test. Set `False` to run silently and just use `GetResult()` / `GetSummary()`. |
137
+ | `raise_errors` | `bool` | `False` | If `True`, invalid input (e.g. wrong number of groups for the chosen test, unequal lengths for a paired test) raises a `ValueError` instead of printing a message and returning an empty/error result. |
138
+ | `groups_name` | `list[str] \| None` | `None` | Labels for your groups, used in the printed summary and available for plotting. If shorter than the number of groups it is cycled (`['A', 'B']` over 4 groups → `A, B, A, B`). Defaults to `Group 1`, `Group 2`, … |
139
+ | `subgrouping` | `list \| None` | `None` | Optional metadata passed through unchanged into the result dict and the plotting module, for experiments with within-group categories (sex, batch, etc.). |
140
+
141
+ ### 2. Running a test
142
+
143
+ Call **`RunAuto()`** to let AutoStatLib decide, or call one of the manual methods if you already know which test you want:
144
+
145
+ | Method | Test performed | Groups required |
146
+ |---|---|---|
147
+ | `RunAuto()` | Automatically selects the test below based on normality, `paired`, and number of groups | any |
148
+ | `RunTtest()` | Independent-samples t-test | 2, independent |
149
+ | `RunMannWhitney()` | Mann-Whitney U test | 2, independent |
150
+ | `RunTtestPaired()` | Paired-samples t-test | 2, paired |
151
+ | `RunWilcoxon()` | Wilcoxon signed-rank test | 2, paired |
152
+ | `RunOnewayAnova()` | Ordinary one-way ANOVA (+ Tukey's post-hoc if `posthoc=True`) | 3+, independent |
153
+ | `RunKruskalWallis()` | Kruskal-Wallis test (+ Dunn's post-hoc if `posthoc=True`) | 3+, independent |
154
+ | `RunOnewayAnovaRM()` | Repeated-measures one-way ANOVA | 3+, paired |
155
+ | `RunFriedman()` | Friedman test | 3+, paired |
156
+ | `RunTtestSingleSample()` | Single-sample t-test against `popmean` | 1 |
157
+ | `RunWilcoxonSingleSample()` | Wilcoxon signed-rank test against `popmean` | 1 |
158
+ | `RunManual(test_id)` | Run any test above by its string ID | — |
159
+
160
+ `GetTestIDs()` returns the list of valid IDs for `RunManual()`, e.g.:
161
+
162
+ ```python
163
+ analysis.GetTestIDs()
164
+ # ['anova_1w_ordinary', 'anova_1w_rm', 'friedman', 'kruskal_wallis',
165
+ # 'mann_whitney', 't_test_independent', 't_test_paired',
166
+ # 't_test_single_sample', 'wilcoxon', 'wilcoxon_single_sample']
167
+
168
+ analysis.RunManual('mann_whitney') # equivalent to analysis.RunMannWhitney()
169
+ ```
170
+
171
+ Calling a manual method on data it isn't suited for (e.g. a parametric test on non-normal data, or a 2-group test on 3 groups) doesn't crash — it either runs anyway and adds a warning to the result (wrong distribution / wrong pairing), or fails validation and returns an error result (wrong number of groups, mismatched paired lengths). See [Warnings](#5-warnings) below.
172
+
173
+ ### 3. How automatic test selection works
174
+
175
+ `RunAuto()` follows this decision logic:
176
+
177
+ 1. **Check normality of every group.** Each group is run through up to four normality tests — Shapiro-Wilk, Lilliefors, Anderson-Darling, and D'Agostino-Pearson (the latter two are skipped for groups smaller than n=20, where they're unreliable). A group is treated as **normally distributed if at least one test says so** — this is intentionally lenient, since requiring unanimous agreement makes the parametric branch too hard to reach with realistic sample sizes.
178
+ 2. **Data is "parametric" only if every group passed.** One non-normal group is enough to route everything to the non-parametric branch.
179
+ 3. **Branch by group count and `paired`:**
180
+
181
+ | Groups | Paired | Parametric | Test |
182
+ |---|---|---|---|
183
+ | 1 | — | yes | Single-sample t-test |
184
+ | 1 | — | no | Wilcoxon signed-rank (single sample) |
185
+ | 2 | No | yes | Independent t-test |
186
+ | 2 | No | no | Mann-Whitney U |
187
+ | 2 | Yes | yes | Paired t-test |
188
+ | 2 | Yes | no | Wilcoxon signed-rank |
189
+ | 3+ | No | yes | One-way ANOVA |
190
+ | 3+ | No | no | Kruskal-Wallis |
191
+ | 3+ | Yes | yes | Repeated-measures ANOVA |
192
+ | 3+ | Yes | no | Friedman |
193
+
194
+ The full normality breakdown (which test passed/failed for each group) is always printed in the verbose log, and the overall `True`/`False` verdict is available in the result dict as `Data_Normaly_Distributed`.
195
+
196
+ > **Note on one-tailed tests:** when `tails=1`, AutoStatLib currently halves the two-tailed p-value. This is only strictly correct when the observed effect is in your hypothesized direction — if you need directional certainty, treat one-tailed results with that caveat in mind, or verify the effect direction yourself before reporting.
197
+
198
+ ### 4. Reading the results
199
+
200
+ ```python
201
+ result = analysis.GetResult()
202
+ ```
203
+
204
+ `GetResult()` returns:
205
+ - a **populated `dict`** if a test ran successfully,
206
+ - `{}` (empty dict) if the test failed validation (and prints an explanatory message),
207
+ - `None` if you haven't called any `Run*()` method yet.
208
+
209
+ Full key reference:
210
+
211
+ ```python
212
+ {
213
+ 'p_value': str, # human-formatted, e.g. "p=0.03" or "p<0.0001"
214
+ 'p_value_exact': float, # raw numeric p-value
215
+ 'Significance(p<0.05)': bool,
216
+ 'Stars': int, # 0-4, number of significance stars
217
+ 'Stars_Printed': str, # 'ns', '*', '**', '***', '****'
218
+ 'Test_Name': str, # e.g. "t-test for independent samples"
219
+ 'Groups_Compared': int,
220
+ 'Population_Mean': float | str, # value of `popmean`, or 'N/A' for multi-group tests
221
+ 'Data_Normaly_Distributed': bool,
222
+ 'Parametric_Test_Applied': bool,
223
+ 'Paired_Test_Applied': bool,
224
+ 'Tails': int, # 1 or 2, echoes the input
225
+
226
+ 'Groups_Name': list[str],
227
+ 'Groups_N': list[int],
228
+ 'Groups_Mean': list[float],
229
+ 'Groups_Median': list[float],
230
+ 'Groups_SD': list[float], # sample SD, ddof=1
231
+ 'Groups_SE': list[float], # standard error of the mean
232
+ 'Samples': list[list[float]], # your cleaned input data, by group
233
+
234
+ 'Posthoc_Tests_Name': str, # '' if posthoc=False
235
+ 'Posthoc_Matrix': list[list[float]], # pairwise p-values, [] if posthoc=False
236
+ 'Posthoc_Matrix_bool': list[list[bool]], # pairwise significance
237
+ 'Posthoc_Matrix_printed': list[list[str]], # human-formatted p-values
238
+ 'Posthoc_Matrix_stars': list[list[str]], # star notation per pair
239
+
240
+ 'Warnings': list[str], # see below
241
+ 'Successfull_Test': bool,
242
+ 'subgrouping': list, # echoes the constructor input
243
+ }
244
+ ```
245
+
246
+ If `posthoc=True` was set and you ran a 3+ group test, `Posthoc_Matrix` is an `N×N` matrix (where `N` is the number of groups) of pairwise comparison p-values, with `1.0` on the diagonal.
247
+
248
+ ### 5. Warnings
249
+
250
+ `result['Warnings']` is a list of human-readable strings describing anything questionable about the analysis — it's empty (`[]`) for a clean run. Warnings are added when:
251
+
252
+ - A parametric test was manually run on data that isn't normally distributed (or vice versa)
253
+ - A paired test was manually run on data declared independent (or vice versa)
254
+ - A single-sample test was run without `popmean` set (defaults to `0`)
255
+
256
+ These don't stop the test from running — they flag results that might be misleading so you can decide whether to trust them or re-run with the correct configuration / `RunAuto()`.
257
+
258
+ ### 6. Text summary
259
+
260
+ For a copy-paste-ready writeup of the whole analysis (data table, normality breakdown, test chosen, full results):
261
+
262
+ ```python
263
+ analysis.PrintSummary() # prints directly to stdout
264
+ text = analysis.GetSummary() # same content, as a string
265
+ ```
266
+
267
+ If `verbose=True` (the default), this same summary is printed automatically every time you call a `Run*()` method.
268
+
269
+ ---
270
+
271
+ ## Plotting results
272
+
273
+ The `AutoStatLib.StatPlots` module turns a finished analysis directly into a matplotlib figure. Each plot class takes your raw data plus (optionally) the exact dictionary returned by `GetResult()`, unpacked as keyword arguments — so the test name, p-value, and post-hoc matrix flow straight from the analysis into the plot without you re-typing anything.
274
+
275
+ ```python
276
+ from AutoStatLib.StatPlots import BarStatPlot
277
+
278
+ result = analysis.GetResult()
279
+
280
+ fig = BarStatPlot(result['Samples'], **result)
281
+ fig.plot()
282
+ fig.show() # or fig.save('figure.png')
283
+ ```
284
+
285
+ Available plot types — all share the same constructor signature and workflow:
286
+
287
+ | Class | Plot style |
288
+ |---|---|
289
+ | `BarStatPlot` | Bar chart of group means with SD error bars and swarm overlay |
290
+ | `ViolinStatPlot` | Violin plot with SD error bars and swarm overlay |
291
+ | `BoxStatPlot` | Box-and-whisker plot with swarm overlay |
292
+ | `ScatterStatPlot` | Mean/median markers with jittered scatter points (lines connect paired data) |
293
+ | `SwarmStatPlot` | Mean/median markers with a non-overlapping swarm plot |
294
+ | `SwarmStatPlot_subgrouping_betta` | Swarm plot with per-subgroup coloring (experimental) |
295
+
296
+ You don't need a `StatisticalAnalysis` result to use these — you can also build a plot directly from raw data and your own values:
297
+
298
+ ```python
299
+ from AutoStatLib.StatPlots import BoxStatPlot
300
+
301
+ fig = BoxStatPlot(
302
+ [group_A, group_B, group_C],
303
+ p_value_exact=0.012,
304
+ Test_Name='Kruskal-Wallis test',
305
+ Groups_Name=['Control', 'Drug A', 'Drug B'],
306
+ plot_title='Effect on firing rate',
307
+ y_label='Hz',
308
+ )
309
+ fig.plot()
310
+ fig.save('result.png', dpi=300)
311
+ ```
312
+
313
+ Useful customization parameters (all optional):
314
+
315
+ | Parameter | Description |
316
+ |---|---|
317
+ | `plot_title`, `x_label`, `y_label` | Figure text |
318
+ | `print_x_labels` | Show/hide group labels on the x-axis |
319
+ | `print_p_label`, `print_stars` | Toggle p-value text and/or star notation on significance bars |
320
+ | `colormap` | List of colors, one per group (falls back to a default palette) |
321
+ | `figure_scale_factor`, `figure_h`, `figure_w` | Figure sizing |
322
+
323
+ Output methods on every plot object: `.plot()` to render, `.show()` to display, `.save(path, format='png', dpi=150)` to export, `.close()` to free the figure.
324
+
325
+ ---
326
+
327
+ ## TODO
328
+
329
+ The project is in alpha dev status. Here is much work to do:
330
+
331
+ -- Anova: posthocs
332
+ -- Anova: add 2-way anova and 3-way anova
333
+ -- onevay Anova: add repeated measures (for normal dependent values) with and without Gaisser-Greenhouse correction
334
+ -- onevay Anova: add Brown-Forsithe and Welch (for normal independent values with unequal SDs between groups)
335
+ -- paired T-test: add ratio-paired t-test (ratios of paired values are consistent)
336
+ -- add Welch test (for norm data unequal variances)
337
+ -- add Kolmogorov-smirnov test (unpaired nonparametric 2 sample, compare cumulative distributions)
338
+ -- add independent t-test with Welch correction (do not assume equal SDs in groups)
339
+ -- add correlation test, correlation diagram
340
+ -- add linear regression, regression diagram
341
+ -- add QQ plot
342
+ -- n-sample tests: add onetail option
343
+
344
+ ✅ done -- detailed normality test results
345
+ ✅ done -- added posthoc: Kruskal-Wallis Dunn's multiple comparisons
346
+
347
+ tests check:
348
+ 1-sample:
349
+ ✅ok --Wilcoxon 2,1 tails
350
+ ✅ok --t-tests 2,1 tails
351
+
352
+ 2-sample:
353
+ ✅ok --Wilcoxon 2,1 tails
354
+ ✅ok --Mann-whitney 2,1 tails
355
+ ✅ok --t-tests 2,1 tails
356
+
357
+ n-sample:
358
+ ✅ok --Kruskal-Wallis 2 tail
359
+ ✅ok --Dunn's multiple comparisons
360
+ ✅ok --Friedman 2 tail
361
+ ✅ok --one-way ANOVA 2-tailed
362
+ ✅ok --Tukey`s multiple comparisons
363
+
364
+
365
+ ---