distfitlab 0.2.0__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.
- distfitlab-0.2.0/.gitignore +40 -0
- distfitlab-0.2.0/CHANGELOG.md +21 -0
- distfitlab-0.2.0/LICENSE +21 -0
- distfitlab-0.2.0/PKG-INFO +161 -0
- distfitlab-0.2.0/README.md +116 -0
- distfitlab-0.2.0/docs/guide.md +147 -0
- distfitlab-0.2.0/examples/quickstart.ipynb +67 -0
- distfitlab-0.2.0/pyproject.toml +52 -0
- distfitlab-0.2.0/src/distfitlab/__init__.py +29 -0
- distfitlab-0.2.0/src/distfitlab/app.py +82 -0
- distfitlab-0.2.0/src/distfitlab/continuous_dist_list.py +139 -0
- distfitlab-0.2.0/src/distfitlab/continuous_helper.py +1543 -0
- distfitlab-0.2.0/src/distfitlab/discrete_dist_list.py +121 -0
- distfitlab-0.2.0/src/distfitlab/discrete_helper.py +1180 -0
- distfitlab-0.2.0/src/distfitlab/file_readers.py +71 -0
- distfitlab-0.2.0/tests/test_smoke.py +115 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Virtual environments
|
|
2
|
+
venv/
|
|
3
|
+
.venv/
|
|
4
|
+
env/
|
|
5
|
+
|
|
6
|
+
# Python bytecode
|
|
7
|
+
__pycache__/
|
|
8
|
+
*.py[cod]
|
|
9
|
+
|
|
10
|
+
# Jupyter
|
|
11
|
+
.ipynb_checkpoints/
|
|
12
|
+
*/.ipynb_checkpoints/
|
|
13
|
+
|
|
14
|
+
# IDE
|
|
15
|
+
.idea/
|
|
16
|
+
.vscode/
|
|
17
|
+
|
|
18
|
+
# macOS
|
|
19
|
+
.DS_Store
|
|
20
|
+
|
|
21
|
+
# R
|
|
22
|
+
.Rhistory
|
|
23
|
+
|
|
24
|
+
# Generated run outputs (timestamped fit results are reproducible; keep them local)
|
|
25
|
+
outputs/
|
|
26
|
+
|
|
27
|
+
# Packaging
|
|
28
|
+
build/
|
|
29
|
+
dist/
|
|
30
|
+
*.egg-info/
|
|
31
|
+
|
|
32
|
+
# Test cache
|
|
33
|
+
.pytest_cache/
|
|
34
|
+
|
|
35
|
+
# Kept locally, not part of the published package
|
|
36
|
+
archive/
|
|
37
|
+
artifacts/
|
|
38
|
+
INVENTORY.md
|
|
39
|
+
requirements.txt
|
|
40
|
+
.Rhistory
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.2.0 — 2026-09-13
|
|
4
|
+
|
|
5
|
+
- First release on PyPI: `pip install distfitlab`.
|
|
6
|
+
- **Data view**: new **Sorted run chart** — values in ascending order against rank, with
|
|
7
|
+
mean and median lines and the same pan/zoom toolbar as the run chart.
|
|
8
|
+
- **grid lines** option for both run charts, applied live to the chart on screen.
|
|
9
|
+
- Run charts are narrower (7 in, was 9 in), since they can be zoomed.
|
|
10
|
+
- README: "After installing" walkthrough and troubleshooting; links now work on the PyPI page.
|
|
11
|
+
|
|
12
|
+
## 0.1.0 — first public release
|
|
13
|
+
|
|
14
|
+
- Two fitting apps behind one switch: 18 continuous distributions and 5 count distributions.
|
|
15
|
+
- **Fit All** ranks every distribution by max |empirical CDF − theoretical CDF|, best first.
|
|
16
|
+
- **Fit** scores a single distribution against parameters you type, with CDF/PDF overlays.
|
|
17
|
+
- **Data view**: histogram / counts bar chart, ECDF, box plot, Q-Q plot, run chart and
|
|
18
|
+
summary statistics, optionally split by group. The run chart has a pan/zoom toolbar.
|
|
19
|
+
- File data: multi-format reader (CSV, Excel, JSON, Parquet, Feather, SPSS/Stata/SAS, HDF5),
|
|
20
|
+
a stack of filter conditions, cleaning options, and group-by that fits every group.
|
|
21
|
+
- **Save results** writes the table, the samples and the figures to a timestamped folder.
|
distfitlab-0.2.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Reza Berangi
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: distfitlab
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Interactive distribution fitting in Jupyter: fit, rank and inspect continuous and count distributions
|
|
5
|
+
Project-URL: Homepage, https://github.com/rberangi/distfitlab
|
|
6
|
+
Project-URL: Source, https://github.com/rberangi/distfitlab
|
|
7
|
+
Project-URL: Issues, https://github.com/rberangi/distfitlab/issues
|
|
8
|
+
Author-email: Reza Berangi <rberangi@gmail.com>
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: distribution fitting,goodness of fit,ipywidgets,jupyter,poisson,scipy,statistics,weibull
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Framework :: Jupyter
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
17
|
+
Requires-Python: >=3.9
|
|
18
|
+
Requires-Dist: ipywidgets>=8.0
|
|
19
|
+
Requires-Dist: matplotlib>=3.9
|
|
20
|
+
Requires-Dist: numpy>=1.23
|
|
21
|
+
Requires-Dist: pandas>=1.5
|
|
22
|
+
Requires-Dist: scipy>=1.9
|
|
23
|
+
Provides-Extra: all
|
|
24
|
+
Requires-Dist: ipympl>=0.9; extra == 'all'
|
|
25
|
+
Requires-Dist: openpyxl; extra == 'all'
|
|
26
|
+
Requires-Dist: pyarrow; extra == 'all'
|
|
27
|
+
Requires-Dist: pyreadstat; extra == 'all'
|
|
28
|
+
Requires-Dist: tables; extra == 'all'
|
|
29
|
+
Provides-Extra: dev
|
|
30
|
+
Requires-Dist: jupyter; extra == 'dev'
|
|
31
|
+
Requires-Dist: nbconvert; extra == 'dev'
|
|
32
|
+
Requires-Dist: nbformat; extra == 'dev'
|
|
33
|
+
Requires-Dist: pytest>=7; extra == 'dev'
|
|
34
|
+
Provides-Extra: excel
|
|
35
|
+
Requires-Dist: openpyxl; extra == 'excel'
|
|
36
|
+
Provides-Extra: hdf5
|
|
37
|
+
Requires-Dist: tables; extra == 'hdf5'
|
|
38
|
+
Provides-Extra: parquet
|
|
39
|
+
Requires-Dist: pyarrow; extra == 'parquet'
|
|
40
|
+
Provides-Extra: spss
|
|
41
|
+
Requires-Dist: pyreadstat; extra == 'spss'
|
|
42
|
+
Provides-Extra: zoom
|
|
43
|
+
Requires-Dist: ipympl>=0.9; extra == 'zoom'
|
|
44
|
+
Description-Content-Type: text/markdown
|
|
45
|
+
|
|
46
|
+
# distfitlab
|
|
47
|
+
|
|
48
|
+
Interactive distribution fitting in Jupyter. Simulate or load data, fit many
|
|
49
|
+
probability distributions at once, see which one fits best, and inspect the data —
|
|
50
|
+
from a single widget UI.
|
|
51
|
+
|
|
52
|
+
Two apps behind one switch:
|
|
53
|
+
|
|
54
|
+
- **Continuous** — 18 distributions: Normal, Exponential, Gamma, Rayleigh, Weibull,
|
|
55
|
+
Lognormal, Loglogistic, Inverse Gaussian, Beta, GEV, Logistic, Laplace, Chi-squared,
|
|
56
|
+
Chi, Nakagami, Rician, Cauchy, Student-T. Fitted with `scipy.stats`.
|
|
57
|
+
- **Discrete** — 5 count distributions: Poisson, Binomial, Geometric, Negative Binomial,
|
|
58
|
+
Zero-Inflated Poisson. SciPy has no `.fit` for these, so the fitters are written here.
|
|
59
|
+
|
|
60
|
+
## Install
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
pip install distfitlab
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Optional readers and the interactive run charts are extras:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
pip install "distfitlab[all]"
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
For the latest development version, install from GitHub instead:
|
|
73
|
+
`pip install "distfitlab[all] @ git+https://github.com/rberangi/distfitlab.git"`.
|
|
74
|
+
|
|
75
|
+
| Extra | Adds |
|
|
76
|
+
|---|---|
|
|
77
|
+
| `excel` | `.xlsx`, `.xls` |
|
|
78
|
+
| `parquet` | `.parquet`, `.feather`, `.arrow` |
|
|
79
|
+
| `spss` | `.sav`, `.dta`, `.sas7bdat`, `.xpt` |
|
|
80
|
+
| `hdf5` | `.h5`, `.hdf5` |
|
|
81
|
+
| `zoom` | pan/zoom toolbar on the run charts |
|
|
82
|
+
| `all` | all of the above |
|
|
83
|
+
|
|
84
|
+
## After installing
|
|
85
|
+
|
|
86
|
+
distfitlab is a widget app, so it runs inside a notebook — not in a plain Python script
|
|
87
|
+
or terminal.
|
|
88
|
+
|
|
89
|
+
**1. Open a notebook** in the same Python environment you installed into:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
pip install jupyterlab # skip if you already have Jupyter
|
|
93
|
+
jupyter lab
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
VS Code works too: create a `.ipynb` file and select that Python as the kernel.
|
|
97
|
+
Notebook 7 is also fine — anywhere `ipywidgets` renders.
|
|
98
|
+
|
|
99
|
+
**2. Start the app** in a notebook cell:
|
|
100
|
+
|
|
101
|
+
```python
|
|
102
|
+
from distfitlab import main
|
|
103
|
+
|
|
104
|
+
main() # opens on the continuous app
|
|
105
|
+
# main("Discrete") # opens on the discrete app
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
**3. Use the UI** that appears below the cell:
|
|
109
|
+
|
|
110
|
+
1. **Data source** — simulate data, or choose **From file** to upload a file (or enter a
|
|
111
|
+
path) and pick the column.
|
|
112
|
+
2. **Fit All** — fit every distribution and get a table ranked best-first.
|
|
113
|
+
3. **Fit** — try one distribution with parameters you type.
|
|
114
|
+
4. **Visualize data** — histogram, ECDF, box plot, Q-Q plot, run charts and summary stats.
|
|
115
|
+
5. **Save results** — write the table and figures to an `outputs/` folder next to the
|
|
116
|
+
notebook.
|
|
117
|
+
|
|
118
|
+
A ready notebook is in [`examples/quickstart.ipynb`](https://github.com/rberangi/distfitlab/blob/main/examples/quickstart.ipynb)
|
|
119
|
+
(in the repository; a pip install does not include it), and every control is explained in
|
|
120
|
+
[`docs/guide.md`](https://github.com/rberangi/distfitlab/blob/main/docs/guide.md).
|
|
121
|
+
|
|
122
|
+
### If something doesn't work
|
|
123
|
+
|
|
124
|
+
| Symptom | Fix |
|
|
125
|
+
|---|---|
|
|
126
|
+
| `ModuleNotFoundError: No module named 'distfitlab'` | The notebook kernel is a different Python from the one pip installed into. Run `%pip install "distfitlab[all]"` in a cell, then restart the kernel. |
|
|
127
|
+
| Text such as `VBox(children=...)` instead of the UI | The frontend can't render widgets. Use JupyterLab 3+, Notebook 7, or VS Code with the Jupyter extension. |
|
|
128
|
+
| No pan/zoom toolbar on the run charts | `ipympl` is missing. Install the `zoom` or `all` extra, then restart the kernel. |
|
|
129
|
+
|
|
130
|
+
## What you get
|
|
131
|
+
|
|
132
|
+
- **Fit All** fits every distribution and ranks them best-first by the largest gap
|
|
133
|
+
between the empirical and theoretical CDF, with the parameters for each.
|
|
134
|
+
- **Fit** scores one distribution against parameters you type, with CDF/PDF overlays.
|
|
135
|
+
- **Data view** — histogram (or counts bar chart), ECDF, box plot, Q-Q plot against the
|
|
136
|
+
distribution you chose, run chart and sorted run chart with a pan/zoom toolbar, and
|
|
137
|
+
summary statistics.
|
|
138
|
+
- **File data** — CSV, TSV, Excel, JSON, Parquet, Feather, SPSS/Stata/SAS and HDF5; a
|
|
139
|
+
stack of filter conditions across columns; cleaning (drop NaN, drop ≤ 0, percentile
|
|
140
|
+
trim, drop duplicates); and **Group by**, which fits every group and ranks them.
|
|
141
|
+
- **loc = 0** option, for when a distribution should be anchored at the origin.
|
|
142
|
+
- **Save results** writes the table, the samples and the figures to a timestamped folder.
|
|
143
|
+
|
|
144
|
+
## Requirements
|
|
145
|
+
|
|
146
|
+
Python 3.9+, with `numpy`, `pandas`, `scipy`, `matplotlib` and `ipywidgets`. Developed
|
|
147
|
+
and tested on Python 3.12.
|
|
148
|
+
|
|
149
|
+
## Documentation
|
|
150
|
+
|
|
151
|
+
The full walkthrough — every control, the parameter conventions, supported file types,
|
|
152
|
+
troubleshooting and how the fitting works — is in [`docs/guide.md`](https://github.com/rberangi/distfitlab/blob/main/docs/guide.md).
|
|
153
|
+
|
|
154
|
+
## License
|
|
155
|
+
|
|
156
|
+
MIT — see [LICENSE](https://github.com/rberangi/distfitlab/blob/main/LICENSE).
|
|
157
|
+
|
|
158
|
+
## Citation
|
|
159
|
+
|
|
160
|
+
If this helps with published work, please cite the libraries it stands on: SciPy, NumPy,
|
|
161
|
+
pandas, Matplotlib and ipywidgets.
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# distfitlab
|
|
2
|
+
|
|
3
|
+
Interactive distribution fitting in Jupyter. Simulate or load data, fit many
|
|
4
|
+
probability distributions at once, see which one fits best, and inspect the data —
|
|
5
|
+
from a single widget UI.
|
|
6
|
+
|
|
7
|
+
Two apps behind one switch:
|
|
8
|
+
|
|
9
|
+
- **Continuous** — 18 distributions: Normal, Exponential, Gamma, Rayleigh, Weibull,
|
|
10
|
+
Lognormal, Loglogistic, Inverse Gaussian, Beta, GEV, Logistic, Laplace, Chi-squared,
|
|
11
|
+
Chi, Nakagami, Rician, Cauchy, Student-T. Fitted with `scipy.stats`.
|
|
12
|
+
- **Discrete** — 5 count distributions: Poisson, Binomial, Geometric, Negative Binomial,
|
|
13
|
+
Zero-Inflated Poisson. SciPy has no `.fit` for these, so the fitters are written here.
|
|
14
|
+
|
|
15
|
+
## Install
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
pip install distfitlab
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Optional readers and the interactive run charts are extras:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pip install "distfitlab[all]"
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
For the latest development version, install from GitHub instead:
|
|
28
|
+
`pip install "distfitlab[all] @ git+https://github.com/rberangi/distfitlab.git"`.
|
|
29
|
+
|
|
30
|
+
| Extra | Adds |
|
|
31
|
+
|---|---|
|
|
32
|
+
| `excel` | `.xlsx`, `.xls` |
|
|
33
|
+
| `parquet` | `.parquet`, `.feather`, `.arrow` |
|
|
34
|
+
| `spss` | `.sav`, `.dta`, `.sas7bdat`, `.xpt` |
|
|
35
|
+
| `hdf5` | `.h5`, `.hdf5` |
|
|
36
|
+
| `zoom` | pan/zoom toolbar on the run charts |
|
|
37
|
+
| `all` | all of the above |
|
|
38
|
+
|
|
39
|
+
## After installing
|
|
40
|
+
|
|
41
|
+
distfitlab is a widget app, so it runs inside a notebook — not in a plain Python script
|
|
42
|
+
or terminal.
|
|
43
|
+
|
|
44
|
+
**1. Open a notebook** in the same Python environment you installed into:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
pip install jupyterlab # skip if you already have Jupyter
|
|
48
|
+
jupyter lab
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
VS Code works too: create a `.ipynb` file and select that Python as the kernel.
|
|
52
|
+
Notebook 7 is also fine — anywhere `ipywidgets` renders.
|
|
53
|
+
|
|
54
|
+
**2. Start the app** in a notebook cell:
|
|
55
|
+
|
|
56
|
+
```python
|
|
57
|
+
from distfitlab import main
|
|
58
|
+
|
|
59
|
+
main() # opens on the continuous app
|
|
60
|
+
# main("Discrete") # opens on the discrete app
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**3. Use the UI** that appears below the cell:
|
|
64
|
+
|
|
65
|
+
1. **Data source** — simulate data, or choose **From file** to upload a file (or enter a
|
|
66
|
+
path) and pick the column.
|
|
67
|
+
2. **Fit All** — fit every distribution and get a table ranked best-first.
|
|
68
|
+
3. **Fit** — try one distribution with parameters you type.
|
|
69
|
+
4. **Visualize data** — histogram, ECDF, box plot, Q-Q plot, run charts and summary stats.
|
|
70
|
+
5. **Save results** — write the table and figures to an `outputs/` folder next to the
|
|
71
|
+
notebook.
|
|
72
|
+
|
|
73
|
+
A ready notebook is in [`examples/quickstart.ipynb`](https://github.com/rberangi/distfitlab/blob/main/examples/quickstart.ipynb)
|
|
74
|
+
(in the repository; a pip install does not include it), and every control is explained in
|
|
75
|
+
[`docs/guide.md`](https://github.com/rberangi/distfitlab/blob/main/docs/guide.md).
|
|
76
|
+
|
|
77
|
+
### If something doesn't work
|
|
78
|
+
|
|
79
|
+
| Symptom | Fix |
|
|
80
|
+
|---|---|
|
|
81
|
+
| `ModuleNotFoundError: No module named 'distfitlab'` | The notebook kernel is a different Python from the one pip installed into. Run `%pip install "distfitlab[all]"` in a cell, then restart the kernel. |
|
|
82
|
+
| Text such as `VBox(children=...)` instead of the UI | The frontend can't render widgets. Use JupyterLab 3+, Notebook 7, or VS Code with the Jupyter extension. |
|
|
83
|
+
| No pan/zoom toolbar on the run charts | `ipympl` is missing. Install the `zoom` or `all` extra, then restart the kernel. |
|
|
84
|
+
|
|
85
|
+
## What you get
|
|
86
|
+
|
|
87
|
+
- **Fit All** fits every distribution and ranks them best-first by the largest gap
|
|
88
|
+
between the empirical and theoretical CDF, with the parameters for each.
|
|
89
|
+
- **Fit** scores one distribution against parameters you type, with CDF/PDF overlays.
|
|
90
|
+
- **Data view** — histogram (or counts bar chart), ECDF, box plot, Q-Q plot against the
|
|
91
|
+
distribution you chose, run chart and sorted run chart with a pan/zoom toolbar, and
|
|
92
|
+
summary statistics.
|
|
93
|
+
- **File data** — CSV, TSV, Excel, JSON, Parquet, Feather, SPSS/Stata/SAS and HDF5; a
|
|
94
|
+
stack of filter conditions across columns; cleaning (drop NaN, drop ≤ 0, percentile
|
|
95
|
+
trim, drop duplicates); and **Group by**, which fits every group and ranks them.
|
|
96
|
+
- **loc = 0** option, for when a distribution should be anchored at the origin.
|
|
97
|
+
- **Save results** writes the table, the samples and the figures to a timestamped folder.
|
|
98
|
+
|
|
99
|
+
## Requirements
|
|
100
|
+
|
|
101
|
+
Python 3.9+, with `numpy`, `pandas`, `scipy`, `matplotlib` and `ipywidgets`. Developed
|
|
102
|
+
and tested on Python 3.12.
|
|
103
|
+
|
|
104
|
+
## Documentation
|
|
105
|
+
|
|
106
|
+
The full walkthrough — every control, the parameter conventions, supported file types,
|
|
107
|
+
troubleshooting and how the fitting works — is in [`docs/guide.md`](https://github.com/rberangi/distfitlab/blob/main/docs/guide.md).
|
|
108
|
+
|
|
109
|
+
## License
|
|
110
|
+
|
|
111
|
+
MIT — see [LICENSE](https://github.com/rberangi/distfitlab/blob/main/LICENSE).
|
|
112
|
+
|
|
113
|
+
## Citation
|
|
114
|
+
|
|
115
|
+
If this helps with published work, please cite the libraries it stands on: SciPy, NumPy,
|
|
116
|
+
pandas, Matplotlib and ipywidgets.
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# distfitlab — user guide
|
|
2
|
+
|
|
3
|
+
This is the full walkthrough. For installation and a one-minute start, see the
|
|
4
|
+
[README](../README.md).
|
|
5
|
+
|
|
6
|
+
## Using the UI
|
|
7
|
+
0) Pick Continuous or Discrete with the switch at the top.
|
|
8
|
+
|
|
9
|
+
1) Data source (on-screen block: DATA SOURCE)
|
|
10
|
+
|
|
11
|
+
Pick **Data Source**, which has two options:
|
|
12
|
+
|
|
13
|
+
Simulated Random Data: choose a **Distribution** and N; a single compact row shows just its parameters.
|
|
14
|
+
UI convention: loc is always first.
|
|
15
|
+
|
|
16
|
+
From file: upload a file or enter a local path, then choose a Column. Use the panel below it to stack filters, clean the column and group rows (all optional). The Distribution list, N and Seed are hidden in this mode, since they only apply to simulated data. CDF bins lives in the **Visualize data** block and stays visible in both modes, because it sets the empirical CDF that every fit is scored against, file data included.
|
|
17
|
+
|
|
18
|
+
Reproducibility: for synthetic data, set Seed; for external data, “Fit” and “Fit All” share a cached empirical baseline so results match.
|
|
19
|
+
|
|
20
|
+
2) Fit all distributions (on-screen block: FIT ALL DISTRIBUTIONS)
|
|
21
|
+
|
|
22
|
+
Continuous only: choose **loc free** (scipy fits loc) or **loc = 0** (loc held at zero) with the radio buttons next to Fit All. With loc = 0, distributions that need positive data cannot be fitted when the data has values ≤ 0; they are skipped and listed in the status line, and the table shows loc = 0 (fixed).
|
|
23
|
+
|
|
24
|
+
Click Fit All to:
|
|
25
|
+
|
|
26
|
+
Fit every supported distribution to the current data.
|
|
27
|
+
|
|
28
|
+
See a parameter table (with Parameter 1 = loc where applicable) and Fitting Error (max CDF deviation).
|
|
29
|
+
|
|
30
|
+
View CDF/PDF overlays for the best fit.
|
|
31
|
+
|
|
32
|
+
Inspect a bar chart of errors (labels printed vertically).
|
|
33
|
+
|
|
34
|
+
3) Fit one distribution (on-screen block: FIT ONE DISTRIBUTION)
|
|
35
|
+
|
|
36
|
+
Pick a distribution, enter parameters, and click Fit to:
|
|
37
|
+
|
|
38
|
+
Compute the max CDF error against the same empirical baseline.
|
|
39
|
+
|
|
40
|
+
Display CDF and PDF overlays for those parameters.
|
|
41
|
+
|
|
42
|
+
4) Visualize data (on-screen block: VISUALIZE DATA, results in the Data view tab)
|
|
43
|
+
|
|
44
|
+
The **Visualize** buttons draw the data you are about to fit - after filters, cleaning and group selection - into the **Data view** tab. **Q-Q plot** uses the distribution and parameters currently in the Fit row, so it answers "do my parameters match this data?" before you fit. **Run chart** plots values in row order, which shows drift or steps that a histogram hides. **Sorted run chart** plots the same values in ascending order against their rank, with mean and median lines, so the range, gaps, ties and outliers stand out; like the run chart it has a pan/zoom toolbar. Tick **grid lines** to add a light grid to both run charts; it applies to a chart already on screen, keeping the current zoom. With a **Group by** column set, tick **split by group** to draw one series per group (up to 10).
|
|
45
|
+
|
|
46
|
+
5) Save results
|
|
47
|
+
|
|
48
|
+
Click Save results to write, into a timestamped folder under outputs/:
|
|
49
|
+
|
|
50
|
+
fitted_parameters.csv, samples.csv
|
|
51
|
+
|
|
52
|
+
fit_errors.png, cdf_overlay.png, pdf_overlay.png
|
|
53
|
+
|
|
54
|
+
Links appear inline in the notebook. Group mode produces no CDF/PDF overlay, so only the files that exist are written.
|
|
55
|
+
|
|
56
|
+
Parameter conventions
|
|
57
|
+
|
|
58
|
+
UI and synthetic generation always show loc first.
|
|
59
|
+
|
|
60
|
+
Fitted parameter table makes Parameter 1 the loc value (when defined).
|
|
61
|
+
|
|
62
|
+
Special notes:
|
|
63
|
+
|
|
64
|
+
Exponential
|
|
65
|
+
|
|
66
|
+
Simulated input uses scale (Distribution → Exponential has “scale”).
|
|
67
|
+
|
|
68
|
+
Fit expects λ (rate); it’s clearly labeled as “λ (rate)”.
|
|
69
|
+
|
|
70
|
+
Internally we convert rate ↔ scale as needed.
|
|
71
|
+
|
|
72
|
+
Beta expects (loc, α, β, scale); support for general location/scale form.
|
|
73
|
+
|
|
74
|
+
Weibull UI uses (loc, k(shape), λ(scale)).
|
|
75
|
+
|
|
76
|
+
Lognormal UI uses (loc, s(shape), scale).
|
|
77
|
+
|
|
78
|
+
GEV UI uses (loc, ξ(shape), scale).
|
|
79
|
+
|
|
80
|
+
All other distributions follow the labels shown in the UI and table.
|
|
81
|
+
|
|
82
|
+
Supported file types (and add-ons)
|
|
83
|
+
Type Ext Notes / Add-on
|
|
84
|
+
CSV/TSV/PSV/TXT .csv, .tsv, .psv, .txt TXT auto-sniffs delimiter; falls back to whitespace
|
|
85
|
+
Excel .xlsx, .xls openpyxl for .xlsx
|
|
86
|
+
JSON .json Standard JSON
|
|
87
|
+
JSON Lines .jsonl, .ndjson lines=True
|
|
88
|
+
Parquet .parquet pyarrow recommended
|
|
89
|
+
Feather / Arrow IPC .feather, .arrow pyarrow required
|
|
90
|
+
SPSS / Stata / SAS .sav, .dta, .sas7bdat, .xpt pyreadstat
|
|
91
|
+
HDF5 .h5, .hdf5 pandas.read_hdf
|
|
92
|
+
MATLAB .mat v5 via scipy.io; v7.3 via h5py
|
|
93
|
+
|
|
94
|
+
Column selection: the column dropdown prioritizes numeric columns; non-numeric are kept for filtering but are not usable for fitting until coerced to numeric.
|
|
95
|
+
|
|
96
|
+
Troubleshooting
|
|
97
|
+
|
|
98
|
+
“Load error: …requires pyarrow/pyreadstat/openpyxl/h5py”
|
|
99
|
+
Install the indicated package (see Quick start).
|
|
100
|
+
|
|
101
|
+
No numeric data in selected column
|
|
102
|
+
Choose a different column or clean/filter data first. The app coerces to numeric and drops non-numeric rows for modeling.
|
|
103
|
+
|
|
104
|
+
Fit vs Fit All mismatch
|
|
105
|
+
|
|
106
|
+
Ensure you didn’t change bins, filter, or seed between actions.
|
|
107
|
+
|
|
108
|
+
The app caches the empirical baseline so both use the same CDF/PDF reference.
|
|
109
|
+
|
|
110
|
+
Widget UI not rendering
|
|
111
|
+
Ensure ipywidgets is installed and enabled; reload the notebook kernel.
|
|
112
|
+
|
|
113
|
+
How it works (internals snapshot)
|
|
114
|
+
|
|
115
|
+
pdf_cdf(x, bins, PDF=True) builds a histogram-based empirical CDF (stable in the tails) and derives an empirical PDF by differencing.
|
|
116
|
+
|
|
117
|
+
datasource(...) generates synthetic arrays using SciPy/NumPy or returns a numeric column from the uploaded DataFrame.
|
|
118
|
+
|
|
119
|
+
theory_cdf/pdf(process, params, x) call SciPy CDF/PDF for each distribution (parameter order mapped from the UI).
|
|
120
|
+
|
|
121
|
+
fit_subset_and_summarize(r, bins, subset):
|
|
122
|
+
|
|
123
|
+
Fits each distribution with scipy.stats.<dist>.fit.
|
|
124
|
+
|
|
125
|
+
Computes max absolute deviation between empirical CDF and theoretical CDF.
|
|
126
|
+
|
|
127
|
+
Builds a table (with loc in Parameter 1 where applicable).
|
|
128
|
+
|
|
129
|
+
A small cache ensures the empirical baseline used in Fit All is reused by Fit.
|
|
130
|
+
|
|
131
|
+
Notes & tips
|
|
132
|
+
|
|
133
|
+
CDF bins (in the **Visualize data** block): affects empirical CDF/PDF smoothness and the histogram detail; 50–200 is a sensible range. It also sets the empirical curve that Fit and Fit All are scored against, for file data as well as simulated data.
|
|
134
|
+
|
|
135
|
+
Scale/shape positivity: the UI enforces positive values for these parameters.
|
|
136
|
+
|
|
137
|
+
Large catalogs: the error bar chart turns labels vertical to stay readable.
|
|
138
|
+
|
|
139
|
+
## Where files are written
|
|
140
|
+
|
|
141
|
+
`Save results` and the formula sheets write under your **current working directory**:
|
|
142
|
+
|
|
143
|
+
- `outputs/fit_outputs_<timestamp>/` — continuous fits
|
|
144
|
+
- `outputs/discrete_fit_outputs_<timestamp>/` — discrete fits
|
|
145
|
+
- `artifacts/` — the rendered formula sheets
|
|
146
|
+
|
|
147
|
+
Run the notebook from the folder you want those in.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{
|
|
2
|
+
"cells": [
|
|
3
|
+
{
|
|
4
|
+
"cell_type": "markdown",
|
|
5
|
+
"id": "0db36152",
|
|
6
|
+
"metadata": {},
|
|
7
|
+
"source": [
|
|
8
|
+
"# distfitlab\n",
|
|
9
|
+
"\n",
|
|
10
|
+
"Fit probability distributions to your data and compare them, from one widget UI.\n",
|
|
11
|
+
"\n",
|
|
12
|
+
"- **Continuous** — 18 distributions (Normal … Student-T), fitted with `scipy.stats`\n",
|
|
13
|
+
"- **Discrete** — 5 count distributions (Poisson, Binomial, Geometric, Negative Binomial, Zero-Inflated Poisson)\n",
|
|
14
|
+
"\n",
|
|
15
|
+
"Use the switch at the top to choose the family. **Fit All** fits every distribution and\n",
|
|
16
|
+
"ranks them; **Fit** checks parameters you enter; the **Data view** tab plots the data itself.\n",
|
|
17
|
+
"\n",
|
|
18
|
+
"Files you save land under your current working directory (`outputs/`, `artifacts/`)."
|
|
19
|
+
]
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"cell_type": "code",
|
|
23
|
+
"execution_count": null,
|
|
24
|
+
"id": "1e496f87",
|
|
25
|
+
"metadata": {},
|
|
26
|
+
"outputs": [],
|
|
27
|
+
"source": [
|
|
28
|
+
"try:\n",
|
|
29
|
+
" from distfitlab import main\n",
|
|
30
|
+
"except ModuleNotFoundError: # opened from a clone without installing: use the sources\n",
|
|
31
|
+
" import sys; sys.path.insert(0, \"../src\")\n",
|
|
32
|
+
" from distfitlab import main\n",
|
|
33
|
+
"\n",
|
|
34
|
+
"main() # Run chart is interactive (pan/zoom); other figures are images"
|
|
35
|
+
]
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"cell_type": "code",
|
|
39
|
+
"execution_count": null,
|
|
40
|
+
"id": "7bcf3489-dd26-41ef-9c5f-f80e4d091468",
|
|
41
|
+
"metadata": {},
|
|
42
|
+
"outputs": [],
|
|
43
|
+
"source": []
|
|
44
|
+
}
|
|
45
|
+
],
|
|
46
|
+
"metadata": {
|
|
47
|
+
"kernelspec": {
|
|
48
|
+
"display_name": "Python 3",
|
|
49
|
+
"language": "python",
|
|
50
|
+
"name": "python3"
|
|
51
|
+
},
|
|
52
|
+
"language_info": {
|
|
53
|
+
"codemirror_mode": {
|
|
54
|
+
"name": "ipython",
|
|
55
|
+
"version": 3
|
|
56
|
+
},
|
|
57
|
+
"file_extension": ".py",
|
|
58
|
+
"mimetype": "text/x-python",
|
|
59
|
+
"name": "python",
|
|
60
|
+
"nbconvert_exporter": "python",
|
|
61
|
+
"pygments_lexer": "ipython3",
|
|
62
|
+
"version": "3.12.7"
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
"nbformat": 4,
|
|
66
|
+
"nbformat_minor": 5
|
|
67
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "distfitlab"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
description = "Interactive distribution fitting in Jupyter: fit, rank and inspect continuous and count distributions"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
13
|
+
authors = [{ name = "Reza Berangi", email = "rberangi@gmail.com" }]
|
|
14
|
+
keywords = ["statistics", "distribution fitting", "jupyter", "ipywidgets",
|
|
15
|
+
"scipy", "goodness of fit", "poisson", "weibull"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 4 - Beta",
|
|
18
|
+
"Framework :: Jupyter",
|
|
19
|
+
"Intended Audience :: Science/Research",
|
|
20
|
+
"Programming Language :: Python :: 3",
|
|
21
|
+
"Topic :: Scientific/Engineering :: Mathematics",
|
|
22
|
+
]
|
|
23
|
+
dependencies = [
|
|
24
|
+
"numpy>=1.23",
|
|
25
|
+
"pandas>=1.5",
|
|
26
|
+
"scipy>=1.9",
|
|
27
|
+
"matplotlib>=3.9", # boxplot(tick_labels=...)
|
|
28
|
+
"ipywidgets>=8.0", # RadioButtons(orientation=...), Tab titles
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
[project.optional-dependencies]
|
|
32
|
+
excel = ["openpyxl"] # .xlsx / .xls
|
|
33
|
+
parquet = ["pyarrow"] # .parquet, .feather, .arrow
|
|
34
|
+
spss = ["pyreadstat"] # .sav, .dta, .sas7bdat, .xpt
|
|
35
|
+
hdf5 = ["tables"] # .h5, .hdf5
|
|
36
|
+
zoom = ["ipympl>=0.9"] # pan/zoom toolbar on the run chart
|
|
37
|
+
all = ["openpyxl", "pyarrow", "pyreadstat", "tables", "ipympl>=0.9"]
|
|
38
|
+
dev = ["pytest>=7", "nbformat", "nbconvert", "jupyter"]
|
|
39
|
+
|
|
40
|
+
[project.urls]
|
|
41
|
+
Homepage = "https://github.com/rberangi/distfitlab"
|
|
42
|
+
Source = "https://github.com/rberangi/distfitlab"
|
|
43
|
+
Issues = "https://github.com/rberangi/distfitlab/issues"
|
|
44
|
+
|
|
45
|
+
[tool.hatch.version]
|
|
46
|
+
path = "src/distfitlab/__init__.py"
|
|
47
|
+
|
|
48
|
+
[tool.hatch.build.targets.wheel]
|
|
49
|
+
packages = ["src/distfitlab"]
|
|
50
|
+
|
|
51
|
+
[tool.hatch.build.targets.sdist]
|
|
52
|
+
include = ["src/distfitlab", "examples", "docs", "tests", "README.md", "LICENSE", "CHANGELOG.md"]
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""distfitlab - interactive distribution fitting in Jupyter.
|
|
2
|
+
|
|
3
|
+
Fit probability distributions to your data, compare them by the largest gap between
|
|
4
|
+
the empirical and theoretical CDF, and inspect the data itself - all from one widget
|
|
5
|
+
UI with two halves:
|
|
6
|
+
|
|
7
|
+
continuous 18 distributions (Normal, Gamma, Weibull, GEV, Student-T, ...)
|
|
8
|
+
discrete 5 count distributions (Poisson, Binomial, Geometric,
|
|
9
|
+
Negative Binomial, Zero-Inflated Poisson)
|
|
10
|
+
|
|
11
|
+
Usage:
|
|
12
|
+
|
|
13
|
+
from distfitlab import main
|
|
14
|
+
main() # opens on the continuous app
|
|
15
|
+
main("Discrete") # opens on the discrete app
|
|
16
|
+
|
|
17
|
+
Building the widgets takes a couple of seconds, so it is deferred until `main` is
|
|
18
|
+
actually looked up rather than done on `import distfitlab`.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
__version__ = "0.2.0"
|
|
22
|
+
__all__ = ["main"]
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def __getattr__(name): # PEP 562: keeps `import distfitlab` cheap
|
|
26
|
+
if name == "main":
|
|
27
|
+
from .app import main
|
|
28
|
+
return main
|
|
29
|
+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|