plot-misc 2.0.4__tar.gz → 2.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.
- {plot_misc-2.0.4/plot_misc.egg-info → plot_misc-2.2.0}/PKG-INFO +68 -19
- {plot_misc-2.0.4 → plot_misc-2.2.0}/README.md +66 -17
- plot_misc-2.2.0/plot_misc/_version.py +1 -0
- {plot_misc-2.0.4 → plot_misc-2.2.0}/plot_misc/barchart.py +3 -3
- {plot_misc-2.0.4 → plot_misc-2.2.0}/plot_misc/errors.py +3 -3
- {plot_misc-2.0.4 → plot_misc-2.2.0}/plot_misc/example_data/examples.py +89 -0
- {plot_misc-2.0.4 → plot_misc-2.2.0}/plot_misc/forest.py +14 -14
- {plot_misc-2.0.4 → plot_misc-2.2.0}/plot_misc/heatmap.py +11 -123
- {plot_misc-2.0.4 → plot_misc-2.2.0}/plot_misc/incidencematrix.py +65 -27
- {plot_misc-2.0.4 → plot_misc-2.2.0}/plot_misc/machine_learning.py +8 -9
- {plot_misc-2.0.4 → plot_misc-2.2.0}/plot_misc/piechart.py +1 -1
- plot_misc-2.2.0/plot_misc/survival.py +628 -0
- {plot_misc-2.0.4 → plot_misc-2.2.0}/plot_misc/utils/colour.py +100 -19
- {plot_misc-2.0.4 → plot_misc-2.2.0}/plot_misc/utils/formatting.py +48 -0
- {plot_misc-2.0.4 → plot_misc-2.2.0}/plot_misc/utils/utils.py +44 -21
- {plot_misc-2.0.4 → plot_misc-2.2.0}/plot_misc/volcano.py +31 -17
- {plot_misc-2.0.4 → plot_misc-2.2.0/plot_misc.egg-info}/PKG-INFO +68 -19
- {plot_misc-2.0.4 → plot_misc-2.2.0}/plot_misc.egg-info/SOURCES.txt +1 -0
- {plot_misc-2.0.4 → plot_misc-2.2.0}/plot_misc.egg-info/dependency_links.txt +0 -0
- {plot_misc-2.0.4 → plot_misc-2.2.0}/plot_misc.egg-info/requires.txt +1 -1
- {plot_misc-2.0.4 → plot_misc-2.2.0}/plot_misc.egg-info/top_level.txt +0 -0
- {plot_misc-2.0.4 → plot_misc-2.2.0}/pyproject.toml +1 -1
- {plot_misc-2.0.4 → plot_misc-2.2.0}/requirements-dev.txt +1 -0
- {plot_misc-2.0.4 → plot_misc-2.2.0}/requirements.txt +0 -1
- plot_misc-2.0.4/plot_misc/_version.py +0 -1
- {plot_misc-2.0.4 → plot_misc-2.2.0}/LICENSE +0 -0
- {plot_misc-2.0.4 → plot_misc-2.2.0}/MANIFEST.in +0 -0
- {plot_misc-2.0.4 → plot_misc-2.2.0}/plot_misc/__init__.py +0 -0
- {plot_misc-2.0.4 → plot_misc-2.2.0}/plot_misc/constants.py +0 -0
- {plot_misc-2.0.4 → plot_misc-2.2.0}/plot_misc/example_data/__init__.py +0 -0
- {plot_misc-2.0.4 → plot_misc-2.2.0}/plot_misc/example_data/example_datasets/bar_points.tsv.gz +0 -0
- {plot_misc-2.0.4 → plot_misc-2.2.0}/plot_misc/example_data/example_datasets/barchart.tsv.gz +0 -0
- {plot_misc-2.0.4 → plot_misc-2.2.0}/plot_misc/example_data/example_datasets/calibration_bins.tsv.gz +0 -0
- {plot_misc-2.0.4 → plot_misc-2.2.0}/plot_misc/example_data/example_datasets/calibration_data.tsv.gz +0 -0
- {plot_misc-2.0.4 → plot_misc-2.2.0}/plot_misc/example_data/example_datasets/forest_data.tsv.gz +0 -0
- {plot_misc-2.0.4 → plot_misc-2.2.0}/plot_misc/example_data/example_datasets/group_bar.tsv.gz +0 -0
- {plot_misc-2.0.4 → plot_misc-2.2.0}/plot_misc/example_data/example_datasets/heatmap_data.tsv.gz +0 -0
- {plot_misc-2.0.4 → plot_misc-2.2.0}/plot_misc/example_data/example_datasets/incidence_matrix_data.tsv.gz +0 -0
- {plot_misc-2.0.4 → plot_misc-2.2.0}/plot_misc/example_data/example_datasets/lollipop_data.tsv.gz +0 -0
- {plot_misc-2.0.4 → plot_misc-2.2.0}/plot_misc/example_data/example_datasets/mace_associations.tsv.gz +0 -0
- {plot_misc-2.0.4 → plot_misc-2.2.0}/plot_misc/example_data/example_datasets/net_benefit.tsv.gz +0 -0
- {plot_misc-2.0.4 → plot_misc-2.2.0}/plot_misc/example_data/example_datasets/string_data.txt +0 -0
- {plot_misc-2.0.4 → plot_misc-2.2.0}/plot_misc/example_data/example_datasets/volcano.tsv.gz +0 -0
- {plot_misc-2.0.4 → plot_misc-2.2.0}/plot_misc/utils/__init__.py +0 -0
- {plot_misc-2.0.4 → plot_misc-2.2.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: plot-misc
|
|
3
|
-
Version: 2.0
|
|
3
|
+
Version: 2.2.0
|
|
4
4
|
Summary: Various plotting templates built on top of matplotlib
|
|
5
5
|
Author-email: A Floriaan Schmidt <floriaanschmidt@gmail.com>
|
|
6
6
|
License-Expression: GPL-3.0-or-later
|
|
@@ -18,7 +18,6 @@ License-File: LICENSE
|
|
|
18
18
|
Requires-Dist: pandas>=1.3
|
|
19
19
|
Requires-Dist: numpy>=1.21
|
|
20
20
|
Requires-Dist: matplotlib>=3.5
|
|
21
|
-
Requires-Dist: seaborn>=0.11
|
|
22
21
|
Requires-Dist: scipy>=1.5
|
|
23
22
|
Requires-Dist: statsmodels>=0.1
|
|
24
23
|
Requires-Dist: scikit-learn>=1.4
|
|
@@ -32,11 +31,14 @@ Requires-Dist: pytest>=6; extra == "dev"
|
|
|
32
31
|
Requires-Dist: pytest-mock>=3; extra == "dev"
|
|
33
32
|
Requires-Dist: pytest-dependency>=0.5; extra == "dev"
|
|
34
33
|
Requires-Dist: bump2version>=1; extra == "dev"
|
|
34
|
+
Requires-Dist: codespell; extra == "dev"
|
|
35
35
|
Requires-Dist: jupyter; extra == "dev"
|
|
36
36
|
Dynamic: license-file
|
|
37
37
|
|
|
38
|
+
<img src="https://schmidtaf.gitlab.io/plot-misc/_images/icon.png" alt="plot-misc icon" width="250"/>
|
|
39
|
+
|
|
38
40
|
# A collection of plotting functions
|
|
39
|
-
__version__: `2.0
|
|
41
|
+
__version__: `2.2.0`
|
|
40
42
|
|
|
41
43
|
This repository collects plotting modules written on top of `matplotlib`.
|
|
42
44
|
The functions are intended to set up light-touch, basic illustrations that
|
|
@@ -46,7 +48,8 @@ covering forest plots, volcano plots, incidence matrices/bubble charts,
|
|
|
46
48
|
illustrations to evaluate prediction models (e.g. feature importance, net benefit, calibration plots),
|
|
47
49
|
and more.
|
|
48
50
|
|
|
49
|
-
The documentation for plot-misc can be found
|
|
51
|
+
The documentation for plot-misc can be found
|
|
52
|
+
[here](https://SchmidtAF.gitlab.io/plot-misc/).
|
|
50
53
|
|
|
51
54
|
## Installation
|
|
52
55
|
The package is available on PyPI, and conda, with the latest source code
|
|
@@ -56,7 +59,7 @@ available on gitlab.
|
|
|
56
59
|
|
|
57
60
|
To install the package from PyPI, run:
|
|
58
61
|
|
|
59
|
-
```
|
|
62
|
+
```bash
|
|
60
63
|
pip install plot-misc
|
|
61
64
|
```
|
|
62
65
|
|
|
@@ -68,49 +71,94 @@ A Conda package is maintained in my personal Conda channel.
|
|
|
68
71
|
To install from this channel, run:
|
|
69
72
|
|
|
70
73
|
|
|
71
|
-
```
|
|
72
|
-
conda install afschmidt::
|
|
74
|
+
```bash
|
|
75
|
+
conda install afschmidt::plot-misc
|
|
73
76
|
```
|
|
74
77
|
|
|
75
78
|
### Installation using gitlab
|
|
76
79
|
|
|
77
|
-
If you require the latest updates, potentially not yet formally released,
|
|
80
|
+
If you require the latest updates, potentially not yet formally released,
|
|
81
|
+
you can install the package directly from GitLab.
|
|
78
82
|
|
|
79
83
|
First, clone the repository and move into its root directory:
|
|
80
84
|
|
|
81
|
-
```
|
|
85
|
+
```bash
|
|
82
86
|
git clone git@gitlab.com:SchmidtAF/plot-misc.git
|
|
83
87
|
cd plot-misc
|
|
84
88
|
```
|
|
85
89
|
|
|
86
90
|
Install the dependencies:
|
|
87
91
|
|
|
88
|
-
```
|
|
92
|
+
```bash
|
|
89
93
|
# From the root of the repository
|
|
90
94
|
conda env create --file ./resources/conda/envs/conda_create.yaml
|
|
91
95
|
```
|
|
92
96
|
|
|
93
97
|
To add to an existing environment use:
|
|
94
98
|
|
|
95
|
-
```
|
|
99
|
+
```bash
|
|
96
100
|
# From the root of the repository
|
|
97
101
|
conda env update --file ./resources/conda/envs/conda_update.yaml
|
|
98
102
|
```
|
|
99
103
|
|
|
100
104
|
Next the package can be installed:
|
|
101
105
|
|
|
102
|
-
```
|
|
103
|
-
|
|
106
|
+
```bash
|
|
107
|
+
make install
|
|
104
108
|
```
|
|
105
109
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
+
#### Development
|
|
111
|
+
For development work, install the package in editable mode with Git commit
|
|
112
|
+
hooks configured:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
make install-dev
|
|
116
|
+
```
|
|
117
|
+
This command installs the package in editable mode and configures Git commit
|
|
118
|
+
hooks, allowing you to run `git pull` to update the repository or switch
|
|
119
|
+
branches without reinstalling.
|
|
110
120
|
|
|
111
|
-
|
|
121
|
+
Alternatively, you can install manually:
|
|
122
|
+
```bash
|
|
112
123
|
python -m pip install -e .
|
|
124
|
+
python .setup_git_hooks.py
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
#### Git Hooks Configuration
|
|
128
|
+
|
|
113
129
|
|
|
130
|
+
When setting up a development environment, the `setup-hooks` command
|
|
131
|
+
configures Git hooks to enforce conventional commit message formatting and
|
|
132
|
+
spell check using `codespell`.
|
|
133
|
+
|
|
134
|
+
To view the commit message format requirements, run:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
./.githooks/commit-msg -help
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
For frequent use, add this function to your shell configuration (`~/.bashrc`
|
|
141
|
+
or `~/.zshrc`):
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
commit-format-help() {
|
|
145
|
+
local git_root
|
|
146
|
+
git_root=$(git rev-parse --show-toplevel 2>/dev/null)
|
|
147
|
+
|
|
148
|
+
if [ -z "$git_root" ]; then
|
|
149
|
+
echo "Error: Not inside a git repository"
|
|
150
|
+
return 1
|
|
151
|
+
fi
|
|
152
|
+
|
|
153
|
+
local hook_path="$git_root/.githooks/commit-msg"
|
|
154
|
+
|
|
155
|
+
if [ ! -f "$hook_path" ]; then
|
|
156
|
+
echo "Error: commit-msg hook not found"
|
|
157
|
+
return 1
|
|
158
|
+
fi
|
|
159
|
+
|
|
160
|
+
"$hook_path" --help
|
|
161
|
+
}
|
|
114
162
|
```
|
|
115
163
|
|
|
116
164
|
#### Validating the package
|
|
@@ -118,7 +166,7 @@ python -m pip install -e .
|
|
|
118
166
|
After installing the package from GitLab, you may wish to run the test
|
|
119
167
|
suite to confirm everything is working as expected:
|
|
120
168
|
|
|
121
|
-
```
|
|
169
|
+
```bash
|
|
122
170
|
# From the root of the repository
|
|
123
171
|
pytest tests
|
|
124
172
|
```
|
|
@@ -129,3 +177,4 @@ Please have a look at the examples in
|
|
|
129
177
|
[resources](https://gitlab.com/SchmidtAF/plot-misc/-/tree/master/resources/examples)
|
|
130
178
|
for some possible recipes.
|
|
131
179
|
|
|
180
|
+
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
<img src="https://schmidtaf.gitlab.io/plot-misc/_images/icon.png" alt="plot-misc icon" width="250"/>
|
|
2
|
+
|
|
1
3
|
# A collection of plotting functions
|
|
2
|
-
__version__: `2.0
|
|
4
|
+
__version__: `2.2.0`
|
|
3
5
|
|
|
4
6
|
This repository collects plotting modules written on top of `matplotlib`.
|
|
5
7
|
The functions are intended to set up light-touch, basic illustrations that
|
|
@@ -9,7 +11,8 @@ covering forest plots, volcano plots, incidence matrices/bubble charts,
|
|
|
9
11
|
illustrations to evaluate prediction models (e.g. feature importance, net benefit, calibration plots),
|
|
10
12
|
and more.
|
|
11
13
|
|
|
12
|
-
The documentation for plot-misc can be found
|
|
14
|
+
The documentation for plot-misc can be found
|
|
15
|
+
[here](https://SchmidtAF.gitlab.io/plot-misc/).
|
|
13
16
|
|
|
14
17
|
## Installation
|
|
15
18
|
The package is available on PyPI, and conda, with the latest source code
|
|
@@ -19,7 +22,7 @@ available on gitlab.
|
|
|
19
22
|
|
|
20
23
|
To install the package from PyPI, run:
|
|
21
24
|
|
|
22
|
-
```
|
|
25
|
+
```bash
|
|
23
26
|
pip install plot-misc
|
|
24
27
|
```
|
|
25
28
|
|
|
@@ -31,49 +34,94 @@ A Conda package is maintained in my personal Conda channel.
|
|
|
31
34
|
To install from this channel, run:
|
|
32
35
|
|
|
33
36
|
|
|
34
|
-
```
|
|
35
|
-
conda install afschmidt::
|
|
37
|
+
```bash
|
|
38
|
+
conda install afschmidt::plot-misc
|
|
36
39
|
```
|
|
37
40
|
|
|
38
41
|
### Installation using gitlab
|
|
39
42
|
|
|
40
|
-
If you require the latest updates, potentially not yet formally released,
|
|
43
|
+
If you require the latest updates, potentially not yet formally released,
|
|
44
|
+
you can install the package directly from GitLab.
|
|
41
45
|
|
|
42
46
|
First, clone the repository and move into its root directory:
|
|
43
47
|
|
|
44
|
-
```
|
|
48
|
+
```bash
|
|
45
49
|
git clone git@gitlab.com:SchmidtAF/plot-misc.git
|
|
46
50
|
cd plot-misc
|
|
47
51
|
```
|
|
48
52
|
|
|
49
53
|
Install the dependencies:
|
|
50
54
|
|
|
51
|
-
```
|
|
55
|
+
```bash
|
|
52
56
|
# From the root of the repository
|
|
53
57
|
conda env create --file ./resources/conda/envs/conda_create.yaml
|
|
54
58
|
```
|
|
55
59
|
|
|
56
60
|
To add to an existing environment use:
|
|
57
61
|
|
|
58
|
-
```
|
|
62
|
+
```bash
|
|
59
63
|
# From the root of the repository
|
|
60
64
|
conda env update --file ./resources/conda/envs/conda_update.yaml
|
|
61
65
|
```
|
|
62
66
|
|
|
63
67
|
Next the package can be installed:
|
|
64
68
|
|
|
65
|
-
```
|
|
66
|
-
|
|
69
|
+
```bash
|
|
70
|
+
make install
|
|
67
71
|
```
|
|
68
72
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
+
#### Development
|
|
74
|
+
For development work, install the package in editable mode with Git commit
|
|
75
|
+
hooks configured:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
make install-dev
|
|
79
|
+
```
|
|
80
|
+
This command installs the package in editable mode and configures Git commit
|
|
81
|
+
hooks, allowing you to run `git pull` to update the repository or switch
|
|
82
|
+
branches without reinstalling.
|
|
73
83
|
|
|
74
|
-
|
|
84
|
+
Alternatively, you can install manually:
|
|
85
|
+
```bash
|
|
75
86
|
python -m pip install -e .
|
|
87
|
+
python .setup_git_hooks.py
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
#### Git Hooks Configuration
|
|
91
|
+
|
|
76
92
|
|
|
93
|
+
When setting up a development environment, the `setup-hooks` command
|
|
94
|
+
configures Git hooks to enforce conventional commit message formatting and
|
|
95
|
+
spell check using `codespell`.
|
|
96
|
+
|
|
97
|
+
To view the commit message format requirements, run:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
./.githooks/commit-msg -help
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
For frequent use, add this function to your shell configuration (`~/.bashrc`
|
|
104
|
+
or `~/.zshrc`):
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
commit-format-help() {
|
|
108
|
+
local git_root
|
|
109
|
+
git_root=$(git rev-parse --show-toplevel 2>/dev/null)
|
|
110
|
+
|
|
111
|
+
if [ -z "$git_root" ]; then
|
|
112
|
+
echo "Error: Not inside a git repository"
|
|
113
|
+
return 1
|
|
114
|
+
fi
|
|
115
|
+
|
|
116
|
+
local hook_path="$git_root/.githooks/commit-msg"
|
|
117
|
+
|
|
118
|
+
if [ ! -f "$hook_path" ]; then
|
|
119
|
+
echo "Error: commit-msg hook not found"
|
|
120
|
+
return 1
|
|
121
|
+
fi
|
|
122
|
+
|
|
123
|
+
"$hook_path" --help
|
|
124
|
+
}
|
|
77
125
|
```
|
|
78
126
|
|
|
79
127
|
#### Validating the package
|
|
@@ -81,7 +129,7 @@ python -m pip install -e .
|
|
|
81
129
|
After installing the package from GitLab, you may wish to run the test
|
|
82
130
|
suite to confirm everything is working as expected:
|
|
83
131
|
|
|
84
|
-
```
|
|
132
|
+
```bash
|
|
85
133
|
# From the root of the repository
|
|
86
134
|
pytest tests
|
|
87
135
|
```
|
|
@@ -92,3 +140,4 @@ Please have a look at the examples in
|
|
|
92
140
|
[resources](https://gitlab.com/SchmidtAF/plot-misc/-/tree/master/resources/examples)
|
|
93
141
|
for some possible recipes.
|
|
94
142
|
|
|
143
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '2.2.0'
|
|
@@ -21,9 +21,9 @@ group_bar(data, label, columns, ...)
|
|
|
21
21
|
Plot a grouped bar chart with multiple bars per group, optionally
|
|
22
22
|
with error bars.
|
|
23
23
|
"""
|
|
24
|
-
import matplotlib.pyplot as plt
|
|
25
24
|
import pandas as pd
|
|
26
25
|
import numpy as np
|
|
26
|
+
import matplotlib.pyplot as plt
|
|
27
27
|
from plot_misc.utils.utils import _update_kwargs
|
|
28
28
|
from plot_misc.errors import (
|
|
29
29
|
is_type,
|
|
@@ -56,7 +56,7 @@ def bar(data:pd.DataFrame, label:str, column:str,
|
|
|
56
56
|
The column name for the bar height values.
|
|
57
57
|
error_max : `str`, default `NoneType`
|
|
58
58
|
column name for the upper value of the error line segment.
|
|
59
|
-
error_min :
|
|
59
|
+
error_min : `str`, default `NoneType`
|
|
60
60
|
column name for the lower value of the error line segment.
|
|
61
61
|
colours : `list` [`str`], default ['tab:blue', 'tab:pink']
|
|
62
62
|
Colours for the bars; recycled if shorter than the number of bars.
|
|
@@ -233,7 +233,7 @@ def stack_bar(data:pd.DataFrame, label:str, columns:list[str],
|
|
|
233
233
|
f, ax = plt.subplots(figsize=figsize)
|
|
234
234
|
else:
|
|
235
235
|
f = ax.figure
|
|
236
|
-
# ### should not be any
|
|
236
|
+
# ### should not be any missing
|
|
237
237
|
# NOTE consider making this into a function
|
|
238
238
|
if any(data.isna().any()):
|
|
239
239
|
raise ValueError(Error_MSG.MISSING_DF.format('data'))
|
|
@@ -111,7 +111,7 @@ def is_type(param: Any, types: tuple[Type] | Type,
|
|
|
111
111
|
if param_name is None:
|
|
112
112
|
param_name = _get_param_name(param)
|
|
113
113
|
else:
|
|
114
|
-
warnings.warn('`param_name` will be
|
|
114
|
+
warnings.warn('`param_name` will be deprecated.',
|
|
115
115
|
DeprecationWarning,
|
|
116
116
|
stacklevel=2,
|
|
117
117
|
)
|
|
@@ -207,7 +207,7 @@ def is_series_type(column: pd.Series | pd.DataFrame, types: tuple[Type] | Type,
|
|
|
207
207
|
----------
|
|
208
208
|
column : `pd.Series` or `pd.DataFrame`
|
|
209
209
|
Data structure to validate.
|
|
210
|
-
types : `type` or `tuple` [`
|
|
210
|
+
types : `type` or `tuple` [`type`]
|
|
211
211
|
Allowed types for individual elements.
|
|
212
212
|
|
|
213
213
|
Returns
|
|
@@ -232,7 +232,7 @@ def is_series_type(column: pd.Series | pd.DataFrame, types: tuple[Type] | Type,
|
|
|
232
232
|
[is_type(col, types) for col in column]
|
|
233
233
|
elif isinstance(column, pd.DataFrame):
|
|
234
234
|
if version.parse('2.0.3') <= version.parse(pd.__version__):
|
|
235
|
-
# iteritems got
|
|
235
|
+
# iteritems got deprecated.
|
|
236
236
|
column.iteritems = column.items
|
|
237
237
|
for _, col in column.items():
|
|
238
238
|
[is_type(co, types) for co in col]
|
|
@@ -635,3 +635,92 @@ def load_mace_associations(**kwargs):
|
|
|
635
635
|
)
|
|
636
636
|
# return
|
|
637
637
|
return df
|
|
638
|
+
|
|
639
|
+
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
640
|
+
def create_survival_data(nrows:int = 50,
|
|
641
|
+
survival_rate:float = 0.02,
|
|
642
|
+
ci_width:float=0.15,
|
|
643
|
+
random_seed:int = 42,
|
|
644
|
+
initial_n:int = 1000) -> pd.DataFrame:
|
|
645
|
+
"""
|
|
646
|
+
Create pilot survival analysis data for testing.
|
|
647
|
+
|
|
648
|
+
Parameters
|
|
649
|
+
----------
|
|
650
|
+
nrows : int, default 50
|
|
651
|
+
Number of time points to generate
|
|
652
|
+
random_seed : int, default 42
|
|
653
|
+
Random seed for reproducibility
|
|
654
|
+
initial_n : int, default 1000
|
|
655
|
+
Initial number of subjects at risk at time zero
|
|
656
|
+
|
|
657
|
+
Returns
|
|
658
|
+
-------
|
|
659
|
+
pd.DataFrame
|
|
660
|
+
DataFrame with survival data including survival estimates,
|
|
661
|
+
confidence intervals, and at-risk counts
|
|
662
|
+
"""
|
|
663
|
+
np.random.seed(random_seed)
|
|
664
|
+
|
|
665
|
+
# Create time points
|
|
666
|
+
time_points = np.linspace(0, 100, nrows)
|
|
667
|
+
|
|
668
|
+
# Generate decreasing survival function with some noise
|
|
669
|
+
base_survival = np.exp(-time_points * survival_rate) # Exponential decay
|
|
670
|
+
noise = np.random.normal(0, 0.01, nrows)
|
|
671
|
+
survival = np.clip(base_survival + noise, 0, 1)
|
|
672
|
+
|
|
673
|
+
# Ensure monotonic decrease
|
|
674
|
+
survival = np.minimum.accumulate(survival)
|
|
675
|
+
|
|
676
|
+
# Generate confidence intervals
|
|
677
|
+
ci_width = ci_width * survival # CI width proportional to survival
|
|
678
|
+
lower_ci = np.clip(survival - ci_width, 0, 1)
|
|
679
|
+
upper_ci = np.clip(survival + ci_width, 0, 1)
|
|
680
|
+
|
|
681
|
+
# Generate at-risk numbers directly from survival probabilities
|
|
682
|
+
at_risk = (survival * initial_n).astype(int)
|
|
683
|
+
|
|
684
|
+
# Create DataFrame
|
|
685
|
+
df = pd.DataFrame({
|
|
686
|
+
'survival_estimate': survival,
|
|
687
|
+
'lower_ci_95': lower_ci,
|
|
688
|
+
'upper_ci_95': upper_ci,
|
|
689
|
+
'at_risk': at_risk,
|
|
690
|
+
'time': time_points
|
|
691
|
+
})
|
|
692
|
+
|
|
693
|
+
df.set_index('time', inplace=True)
|
|
694
|
+
return df
|
|
695
|
+
|
|
696
|
+
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
697
|
+
@dataset
|
|
698
|
+
def load_survival_table(**kwargs):
|
|
699
|
+
"""
|
|
700
|
+
Returns a survival table with information on the `time` (in days) an event
|
|
701
|
+
occurred the cumulative events per discordancy group. The time per year
|
|
702
|
+
is provided as the time_format column.
|
|
703
|
+
|
|
704
|
+
Returns
|
|
705
|
+
-------
|
|
706
|
+
pd.DataFrame
|
|
707
|
+
"""
|
|
708
|
+
# data
|
|
709
|
+
table = pd.DataFrame(
|
|
710
|
+
{
|
|
711
|
+
'time': [0, 365, 730, 1095, 1461, 1826, 2191, 2556, 2922, 3287,
|
|
712
|
+
3652, 4017, 4383, 4748, 5113, 5478],
|
|
713
|
+
'Not Discordant': ['268,196', '263,426', '258,484', '254,009',
|
|
714
|
+
'249,315', '244,907', '240,562', '236,574',
|
|
715
|
+
'233,347', '230,368', '227,648', '224,916',
|
|
716
|
+
'222,169', '172,545', '95,987', '15,280'],
|
|
717
|
+
'Discordant': ['5,749', '5,629', '5,494', '5,374',
|
|
718
|
+
'5,245', '5,129', '5,029', '4,935',
|
|
719
|
+
'4,863', '4,777', '4,714', '4,634',
|
|
720
|
+
'4,558', '3,586', '2,030', '346'],
|
|
721
|
+
'time_format': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
|
|
722
|
+
}, **kwargs,
|
|
723
|
+
)
|
|
724
|
+
# return
|
|
725
|
+
return table
|
|
726
|
+
|
|
@@ -394,9 +394,9 @@ class ForestPlot(object):
|
|
|
394
394
|
- 'max' : float
|
|
395
395
|
The upper bound of the span in data coordinates.
|
|
396
396
|
- 'kwargs' : dict
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
397
|
+
A dictionary of keyword arguments to be passed to the span plotting
|
|
398
|
+
function (e.g., `ax.axhspan()`), such as `facecolor`, `alpha`,
|
|
399
|
+
`zorder`, etc.
|
|
400
400
|
|
|
401
401
|
Notes
|
|
402
402
|
-----
|
|
@@ -587,7 +587,7 @@ class ForestPlot(object):
|
|
|
587
587
|
is_type(span_colour, list)
|
|
588
588
|
is_type(reverse_y, bool)
|
|
589
589
|
is_type(ylim, (type(None), tuple))
|
|
590
|
-
# ### set
|
|
590
|
+
# ### set defaults
|
|
591
591
|
# replace None by empty dict
|
|
592
592
|
kwargs_scatter_dict = kwargs_scatter_dict or {}
|
|
593
593
|
kwargs_plot_ci_dict = kwargs_plot_ci_dict or {}
|
|
@@ -701,7 +701,7 @@ class ForestPlot(object):
|
|
|
701
701
|
y_mid.insert(0, y_locations.iloc[0][FNames.min])
|
|
702
702
|
y_mid[-1] = self.ax.get_ylim()[1] # replace with y-axis limit
|
|
703
703
|
# ################### Add horizontal segments
|
|
704
|
-
# to store the span y-axis
|
|
704
|
+
# to store the span y-axis coordinates, colours
|
|
705
705
|
if span ==True:
|
|
706
706
|
span_dict = {}
|
|
707
707
|
# add segments
|
|
@@ -767,7 +767,7 @@ def plot_table(
|
|
|
767
767
|
Parameters
|
|
768
768
|
----------
|
|
769
769
|
data : `pd.DataFrame`
|
|
770
|
-
Pandas DataFrame
|
|
770
|
+
Pandas DataFrame containing `string_col` that should be plotted.
|
|
771
771
|
margin of error, etc.
|
|
772
772
|
ax : plt.axes
|
|
773
773
|
Axes to operate on.
|
|
@@ -858,7 +858,7 @@ def plot_table(
|
|
|
858
858
|
kwargs_yticklabel_dict = kwargs_yticklabel_dict or {}
|
|
859
859
|
# ################### remove spines
|
|
860
860
|
ax.spines[['top', 'right', 'bottom', 'left']].set_visible(False)
|
|
861
|
-
# remove
|
|
861
|
+
# remove labels
|
|
862
862
|
ax.xaxis.set_ticklabels([])
|
|
863
863
|
# remove ticks
|
|
864
864
|
ax.set_xticks([])
|
|
@@ -869,7 +869,7 @@ def plot_table(
|
|
|
869
869
|
raise ValueError('`yticklabel` should be supplied if `ytickloc` is defined.')
|
|
870
870
|
if (not yticklabel is None) and (not ytickloc is None):
|
|
871
871
|
if len(yticklabel) != len(ytickloc):
|
|
872
|
-
raise IndexError('`yticklabel` and `ytickloc`
|
|
872
|
+
raise IndexError('`yticklabel` and `ytickloc` contains distinct values.')
|
|
873
873
|
# add optional label padding
|
|
874
874
|
if not l_yticklab_pad is None:
|
|
875
875
|
yticklabel = [l_yticklab_pad + str(s) for s in yticklabel]
|
|
@@ -1000,15 +1000,15 @@ class EmpericalSupport(object):
|
|
|
1000
1000
|
-----
|
|
1001
1001
|
This implementation is based on the concept of compatibility (or
|
|
1002
1002
|
confidence) curves, which visualise the range of parameter values supported
|
|
1003
|
-
by the data across a continuum of alpha levels [
|
|
1003
|
+
by the data across a continuum of alpha levels [ES1]_, [ES2]_.
|
|
1004
1004
|
|
|
1005
1005
|
References
|
|
1006
1006
|
----------
|
|
1007
|
-
.. [
|
|
1007
|
+
.. [ES1] Amrhein, V., Greenland, S., & McShane, B. B. (2019).
|
|
1008
1008
|
Scientists rise up against statistical significance.
|
|
1009
1009
|
*Nature*, 567(7748), 305–307. https://doi.org/10.1038/d41586-019-00857-9
|
|
1010
1010
|
|
|
1011
|
-
.. [
|
|
1011
|
+
.. [ES2] Van der Burg, S. H., & Gelman, A. (2020).
|
|
1012
1012
|
Empirical support plots and compatibility intervals.
|
|
1013
1013
|
*BMC Medical Research Methodology*, 20, Article 109.
|
|
1014
1014
|
https://doi.org/10.1186/s12874-020-01105-9
|
|
@@ -1026,7 +1026,7 @@ class EmpericalSupport(object):
|
|
|
1026
1026
|
is_type(estimate, (int, float))
|
|
1027
1027
|
is_type(standard_error, (int, float))
|
|
1028
1028
|
is_type(alpha, (list, np.ndarray))
|
|
1029
|
-
#
|
|
1029
|
+
# assign
|
|
1030
1030
|
self.estimate=estimate
|
|
1031
1031
|
self.standard_error=standard_error
|
|
1032
1032
|
self.alpha=alpha
|
|
@@ -1304,10 +1304,10 @@ class EmpericalSupport(object):
|
|
|
1304
1304
|
kwargs_text:dict[Any,Any] | None = None,
|
|
1305
1305
|
)-> tuple[plt.Figure, plt.Axes]:
|
|
1306
1306
|
"""
|
|
1307
|
-
Plots an
|
|
1307
|
+
Plots an Empirical Support graph based on either `coverage` (iterating
|
|
1308
1308
|
the confidence interval coverage percentage), or `compatibility`
|
|
1309
1309
|
(iterating the p-value). Due to its Christmas tree like shape this
|
|
1310
|
-
type of illustration is
|
|
1310
|
+
type of illustration is referred to as a `tree plot`.
|
|
1311
1311
|
|
|
1312
1312
|
Parameters
|
|
1313
1313
|
----------
|