plot-misc 2.0.3__tar.gz → 2.1.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.1.0/MANIFEST.in +16 -0
- {plot_misc-2.0.3 → plot_misc-2.1.0}/PKG-INFO +22 -11
- {plot_misc-2.0.3 → plot_misc-2.1.0}/README.md +4 -2
- plot_misc-2.1.0/plot_misc/_version.py +1 -0
- {plot_misc-2.0.3 → plot_misc-2.1.0}/plot_misc/barchart.py +24 -16
- {plot_misc-2.0.3 → plot_misc-2.1.0}/plot_misc/example_data/examples.py +89 -0
- {plot_misc-2.0.3 → plot_misc-2.1.0}/plot_misc/forest.py +6 -6
- {plot_misc-2.0.3 → plot_misc-2.1.0}/plot_misc/heatmap.py +10 -2
- {plot_misc-2.0.3 → plot_misc-2.1.0}/plot_misc/incidencematrix.py +33 -5
- {plot_misc-2.0.3 → plot_misc-2.1.0}/plot_misc/machine_learning.py +1 -2
- plot_misc-2.1.0/plot_misc/survival.py +628 -0
- {plot_misc-2.0.3 → plot_misc-2.1.0}/plot_misc/utils/colour.py +105 -8
- {plot_misc-2.0.3 → plot_misc-2.1.0}/plot_misc/utils/formatting.py +48 -0
- {plot_misc-2.0.3 → plot_misc-2.1.0}/plot_misc/utils/utils.py +41 -18
- {plot_misc-2.0.3 → plot_misc-2.1.0}/plot_misc.egg-info/PKG-INFO +22 -11
- {plot_misc-2.0.3 → plot_misc-2.1.0}/plot_misc.egg-info/SOURCES.txt +4 -0
- {plot_misc-2.0.3 → plot_misc-2.1.0}/plot_misc.egg-info/dependency_links.txt +0 -0
- plot_misc-2.1.0/plot_misc.egg-info/requires.txt +19 -0
- {plot_misc-2.0.3 → plot_misc-2.1.0}/plot_misc.egg-info/top_level.txt +0 -0
- {plot_misc-2.0.3 → plot_misc-2.1.0}/pyproject.toml +9 -13
- plot_misc-2.1.0/requirements-dev.txt +9 -0
- plot_misc-2.1.0/requirements.txt +9 -0
- plot_misc-2.0.3/plot_misc/_version.py +0 -1
- plot_misc-2.0.3/plot_misc.egg-info/requires.txt +0 -11
- {plot_misc-2.0.3 → plot_misc-2.1.0}/LICENSE +0 -0
- {plot_misc-2.0.3 → plot_misc-2.1.0}/plot_misc/__init__.py +0 -0
- {plot_misc-2.0.3 → plot_misc-2.1.0}/plot_misc/constants.py +0 -0
- {plot_misc-2.0.3 → plot_misc-2.1.0}/plot_misc/errors.py +0 -0
- {plot_misc-2.0.3 → plot_misc-2.1.0}/plot_misc/example_data/__init__.py +0 -0
- {plot_misc-2.0.3 → plot_misc-2.1.0}/plot_misc/example_data/example_datasets/bar_points.tsv.gz +0 -0
- {plot_misc-2.0.3 → plot_misc-2.1.0}/plot_misc/example_data/example_datasets/barchart.tsv.gz +0 -0
- {plot_misc-2.0.3 → plot_misc-2.1.0}/plot_misc/example_data/example_datasets/calibration_bins.tsv.gz +0 -0
- {plot_misc-2.0.3 → plot_misc-2.1.0}/plot_misc/example_data/example_datasets/calibration_data.tsv.gz +0 -0
- {plot_misc-2.0.3 → plot_misc-2.1.0}/plot_misc/example_data/example_datasets/forest_data.tsv.gz +0 -0
- {plot_misc-2.0.3 → plot_misc-2.1.0}/plot_misc/example_data/example_datasets/group_bar.tsv.gz +0 -0
- {plot_misc-2.0.3 → plot_misc-2.1.0}/plot_misc/example_data/example_datasets/heatmap_data.tsv.gz +0 -0
- {plot_misc-2.0.3 → plot_misc-2.1.0}/plot_misc/example_data/example_datasets/incidence_matrix_data.tsv.gz +0 -0
- {plot_misc-2.0.3 → plot_misc-2.1.0}/plot_misc/example_data/example_datasets/lollipop_data.tsv.gz +0 -0
- {plot_misc-2.0.3 → plot_misc-2.1.0}/plot_misc/example_data/example_datasets/mace_associations.tsv.gz +0 -0
- {plot_misc-2.0.3 → plot_misc-2.1.0}/plot_misc/example_data/example_datasets/net_benefit.tsv.gz +0 -0
- {plot_misc-2.0.3 → plot_misc-2.1.0}/plot_misc/example_data/example_datasets/string_data.txt +0 -0
- {plot_misc-2.0.3 → plot_misc-2.1.0}/plot_misc/example_data/example_datasets/volcano.tsv.gz +0 -0
- {plot_misc-2.0.3 → plot_misc-2.1.0}/plot_misc/piechart.py +0 -0
- {plot_misc-2.0.3 → plot_misc-2.1.0}/plot_misc/utils/__init__.py +0 -0
- {plot_misc-2.0.3 → plot_misc-2.1.0}/plot_misc/volcano.py +0 -0
- {plot_misc-2.0.3 → plot_misc-2.1.0}/setup.cfg +0 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# include top-level metadata
|
|
2
|
+
include README.md LICENSE
|
|
3
|
+
include requirements.txt
|
|
4
|
+
include requirements-dev.txt
|
|
5
|
+
|
|
6
|
+
# ship the example datasets explicitly
|
|
7
|
+
recursive-include plot_misc/example_data/example_datasets *.tsv.gz *.txt
|
|
8
|
+
|
|
9
|
+
# drop these
|
|
10
|
+
prune tests
|
|
11
|
+
prune resources
|
|
12
|
+
|
|
13
|
+
# drop the rest
|
|
14
|
+
global-exclude .*
|
|
15
|
+
global-exclude *.py[cod]
|
|
16
|
+
global-exclude __pycache__/*
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: plot-misc
|
|
3
|
-
Version: 2.0
|
|
3
|
+
Version: 2.1.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
|
|
7
7
|
Project-URL: Homepage, https://gitlab.com/SchmidtAF/plot-misc
|
|
8
|
+
Project-URL: Documentation, https://schmidtaf.gitlab.io/plot-misc/
|
|
8
9
|
Classifier: Programming Language :: Python
|
|
9
10
|
Classifier: Programming Language :: Python :: 3
|
|
10
11
|
Classifier: Programming Language :: Python :: 3.10
|
|
@@ -14,20 +15,30 @@ Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
|
14
15
|
Requires-Python: <3.13,>=3.10
|
|
15
16
|
Description-Content-Type: text/markdown
|
|
16
17
|
License-File: LICENSE
|
|
17
|
-
Requires-Dist:
|
|
18
|
-
Requires-Dist:
|
|
19
|
-
Requires-Dist: matplotlib
|
|
20
|
-
Requires-Dist: seaborn
|
|
21
|
-
Requires-Dist: scipy
|
|
22
|
-
Requires-Dist:
|
|
23
|
-
Requires-Dist:
|
|
18
|
+
Requires-Dist: pandas>=1.3
|
|
19
|
+
Requires-Dist: numpy>=1.21
|
|
20
|
+
Requires-Dist: matplotlib>=3.5
|
|
21
|
+
Requires-Dist: seaborn>=0.11
|
|
22
|
+
Requires-Dist: scipy>=1.5
|
|
23
|
+
Requires-Dist: statsmodels>=0.1
|
|
24
|
+
Requires-Dist: scikit-learn>=1.4
|
|
25
|
+
Requires-Dist: adjustText>=1.3
|
|
24
26
|
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: python-build; extra == "dev"
|
|
25
28
|
Requires-Dist: twine; extra == "dev"
|
|
26
|
-
Requires-Dist:
|
|
29
|
+
Requires-Dist: setuptools; extra == "dev"
|
|
30
|
+
Requires-Dist: wheel; extra == "dev"
|
|
31
|
+
Requires-Dist: pytest>=6; extra == "dev"
|
|
32
|
+
Requires-Dist: pytest-mock>=3; extra == "dev"
|
|
33
|
+
Requires-Dist: pytest-dependency>=0.5; extra == "dev"
|
|
34
|
+
Requires-Dist: bump2version>=1; extra == "dev"
|
|
35
|
+
Requires-Dist: jupyter; extra == "dev"
|
|
27
36
|
Dynamic: license-file
|
|
28
37
|
|
|
38
|
+
<img src="https://schmidtaf.gitlab.io/plot-misc/_images/icon.png" alt="plot-misc icon" width="250"/>
|
|
39
|
+
|
|
29
40
|
# A collection of plotting functions
|
|
30
|
-
__version__: `2.0
|
|
41
|
+
__version__: `2.1.0`
|
|
31
42
|
|
|
32
43
|
This repository collects plotting modules written on top of `matplotlib`.
|
|
33
44
|
The functions are intended to set up light-touch, basic illustrations that
|
|
@@ -60,7 +71,7 @@ To install from this channel, run:
|
|
|
60
71
|
|
|
61
72
|
|
|
62
73
|
```sh
|
|
63
|
-
conda install afschmidt::
|
|
74
|
+
conda install afschmidt::plot-misc
|
|
64
75
|
```
|
|
65
76
|
|
|
66
77
|
### Installation using gitlab
|
|
@@ -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.1.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
|
|
@@ -32,7 +34,7 @@ To install from this channel, run:
|
|
|
32
34
|
|
|
33
35
|
|
|
34
36
|
```sh
|
|
35
|
-
conda install afschmidt::
|
|
37
|
+
conda install afschmidt::plot-misc
|
|
36
38
|
```
|
|
37
39
|
|
|
38
40
|
### Installation using gitlab
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '2.1.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.
|
|
@@ -83,6 +83,14 @@ def bar(data:pd.DataFrame, label:str, column:str,
|
|
|
83
83
|
Matplotlib figure object.
|
|
84
84
|
ax : plt.Axes
|
|
85
85
|
Matplotlib axes with the rendered bar plot.
|
|
86
|
+
|
|
87
|
+
Notes
|
|
88
|
+
-----
|
|
89
|
+
This function is essentially a helper function for the more complicated
|
|
90
|
+
bar charts in this module and simply wraps matplotlib's bar function.
|
|
91
|
+
It is included as a public function to allow people to use the same
|
|
92
|
+
interface when working with plot-misc. If one is exclusively looking to
|
|
93
|
+
use `bar` it is advisable to simply revert to matplotlib's offering.
|
|
86
94
|
"""
|
|
87
95
|
# check input
|
|
88
96
|
is_df(data)
|
|
@@ -235,30 +243,30 @@ def stack_bar(data:pd.DataFrame, label:str, columns:list[str],
|
|
|
235
243
|
'number of colours ({1}).'.format(
|
|
236
244
|
len(columns), len(colours)))
|
|
237
245
|
# get labels
|
|
238
|
-
labels = data[label]
|
|
246
|
+
# labels = data[label]
|
|
239
247
|
# get columns
|
|
240
248
|
fields=columns
|
|
241
249
|
# actual plotting
|
|
242
250
|
left = len(data) * [0]
|
|
243
251
|
for idx, name in enumerate(fields):
|
|
252
|
+
new_kwargs = _update_kwargs(update_dict=kwargs,
|
|
253
|
+
edgecolor=edgecolour,
|
|
254
|
+
color=colours[idx],
|
|
255
|
+
alpha=transparency,
|
|
256
|
+
)
|
|
244
257
|
if horizontal == False:
|
|
245
|
-
|
|
246
|
-
new_kwargs = _update_kwargs(update_dict=kwargs,
|
|
247
|
-
edgecolor=edgecolour,
|
|
248
|
-
width=wd, color=colours[idx],
|
|
249
|
-
alpha=transparency,
|
|
258
|
+
new_kwargs = _update_kwargs(new_kwargs, bottom=left,
|
|
250
259
|
)
|
|
251
|
-
ax.bar(labels, height=data[name], bottom=left, **new_kwargs,
|
|
252
|
-
)
|
|
253
260
|
else:
|
|
254
|
-
|
|
255
|
-
new_kwargs = _update_kwargs(update_dict=kwargs, edgecolor=edgecolour,
|
|
256
|
-
height=wd, color=colours[idx],
|
|
257
|
-
alpha=transparency,
|
|
261
|
+
new_kwargs = _update_kwargs(new_kwargs, left=left,
|
|
258
262
|
)
|
|
259
|
-
|
|
263
|
+
# The actual plotting
|
|
264
|
+
# NOTE adding wd here because it bar assigns it to either width or
|
|
265
|
+
# height depending on horizontal.
|
|
266
|
+
_, ax = bar(data=data, label=label, column=name, horizontal=horizontal,
|
|
267
|
+
wd=wd, ax=ax, kwargs_bar=new_kwargs,
|
|
260
268
|
)
|
|
261
|
-
#
|
|
269
|
+
# updating the coordinate where the last bar stops
|
|
262
270
|
left = left + data[name]
|
|
263
271
|
# removing spines
|
|
264
272
|
ax.spines['right'].set_visible(False)
|
|
@@ -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
|
+
occured the cummulative 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
|
-----
|
|
@@ -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
|
|
@@ -28,7 +28,9 @@ from the example published in the official matplotlib gallery [1]_.
|
|
|
28
28
|
|
|
29
29
|
References
|
|
30
30
|
----------
|
|
31
|
-
.. [1]
|
|
31
|
+
.. [1] Matplotlib contributors. "Creating annotated heatmaps."
|
|
32
|
+
Matplotlib Gallery.
|
|
33
|
+
https://matplotlib.org/stable/gallery/images_contours_and_fields/image_annotated_heatmap.html
|
|
32
34
|
"""
|
|
33
35
|
|
|
34
36
|
# modules
|
|
@@ -105,7 +107,13 @@ def heatmap(data:pd.DataFrame | np.ndarray, row_labels:list[str] | np.ndarray,
|
|
|
105
107
|
The returned objects can be used to annotate the cells using for example
|
|
106
108
|
`annotate_heatmap`.
|
|
107
109
|
|
|
108
|
-
This function is adapted from the matplotlib gallery example [
|
|
110
|
+
This function is adapted from the matplotlib gallery example [HM1]_.
|
|
111
|
+
|
|
112
|
+
References
|
|
113
|
+
----------
|
|
114
|
+
.. [HM1] Matplotlib contributors. "Creating annotated heatmaps."
|
|
115
|
+
Matplotlib Gallery.
|
|
116
|
+
https://matplotlib.org/stable/gallery/images_contours_and_fields/image_annotated_heatmap.html
|
|
109
117
|
"""
|
|
110
118
|
|
|
111
119
|
# create a axes if needed
|
|
@@ -61,6 +61,8 @@ def draw_incidencematrix(
|
|
|
61
61
|
margins:tuple[float,float] | None = None,
|
|
62
62
|
grid_position:Literal['outline', 'centre'] | None = 'centre',
|
|
63
63
|
ax:plt.Axes | None = None,
|
|
64
|
+
x_coords:list[Real] | None = None,
|
|
65
|
+
y_coords:list[Real] | None = None,
|
|
64
66
|
break_limits:tuple[float, float] = (-np.inf, np.inf),
|
|
65
67
|
size_data: pd.DataFrame | None = None,
|
|
66
68
|
transparency_data: pd.DataFrame | None = None,
|
|
@@ -119,6 +121,14 @@ def draw_incidencematrix(
|
|
|
119
121
|
ax : `plt.axes` or `None`, default `None`
|
|
120
122
|
If provided, the plot is drawn on this axis. Otherwise, a new figure
|
|
121
123
|
and axis are created.
|
|
124
|
+
x_coords : `list` [`real`] or `None`, default `None`
|
|
125
|
+
An optional list of x-coordinates to use for plotting the dots.
|
|
126
|
+
If `None`, dots are spaced evenly. Length must match number of
|
|
127
|
+
rows in `data`.
|
|
128
|
+
y_coords : `list` [`real`] or `None`, default `None`
|
|
129
|
+
An optional list of y-coordinates to use for plotting the dots.
|
|
130
|
+
If `None`, dots are spaced evenly. Length must match number of
|
|
131
|
+
columns in `data`.
|
|
122
132
|
break_limits : `tuple` [`float`, `float`], default (-np.inf, np.inf)
|
|
123
133
|
Lower and upper bounds for the first and final break. Used to define
|
|
124
134
|
open-ended ranges in dot colouring. Currently only uses the lower
|
|
@@ -148,8 +158,9 @@ def draw_incidencematrix(
|
|
|
148
158
|
|
|
149
159
|
Missing or non-matching entries in the input matrix will be ignored.
|
|
150
160
|
"""
|
|
151
|
-
|
|
161
|
+
SHAPE_ERR1 = ('`data` and `{0}` should have the same shapes '
|
|
152
162
|
'not: {1} and {2}, respectively.')
|
|
163
|
+
SHAPE_ERR2 = ('Length of {0}: {1} must match number of {2}: {3}.')
|
|
153
164
|
# check inputs
|
|
154
165
|
is_type(dot_size, list)
|
|
155
166
|
is_type(dot_colour, list)
|
|
@@ -159,6 +170,8 @@ def draw_incidencematrix(
|
|
|
159
170
|
is_type(grid_position, (str, type(None)))
|
|
160
171
|
is_type(size_data, (type(None), pd.DataFrame))
|
|
161
172
|
is_type(transparency_data, (type(None), pd.DataFrame))
|
|
173
|
+
is_type(x_coords, (type(None), list))
|
|
174
|
+
is_type(y_coords, (type(None), list))
|
|
162
175
|
# check literals
|
|
163
176
|
EXP_GRID = [NamesIM.GRID_POS_B, NamesIM.GRID_POS_O]
|
|
164
177
|
if grid_position is not None and not grid_position in EXP_GRID:
|
|
@@ -168,11 +181,11 @@ def draw_incidencematrix(
|
|
|
168
181
|
# make sure all the data have the same shape
|
|
169
182
|
if size_data is not None and data.shape != size_data.shape:
|
|
170
183
|
raise IndexError(
|
|
171
|
-
|
|
184
|
+
SHAPE_ERR1.format('size_data', data.shape, size_data.shape
|
|
172
185
|
))
|
|
173
186
|
if transparency_data is not None and data.shape != transparency_data.shape:
|
|
174
187
|
raise IndexError(
|
|
175
|
-
|
|
188
|
+
SHAPE_ERR1.format('transparency_data', data.shape,
|
|
176
189
|
transparency_data.shape
|
|
177
190
|
))
|
|
178
191
|
# transpose - hack to make the output match the input row,col and order.
|
|
@@ -221,9 +234,24 @@ def draw_incidencematrix(
|
|
|
221
234
|
dot_transparency_arr = _map_attributes(
|
|
222
235
|
transparency_input, new_dot_transparency,
|
|
223
236
|
break_limits=break_limits)
|
|
224
|
-
#
|
|
237
|
+
# All for user supplied coordinates and check these match the data shape
|
|
225
238
|
M, N = data.shape
|
|
226
|
-
|
|
239
|
+
if x_coords is not None:
|
|
240
|
+
x_coords_ = np.asarray(x_coords)
|
|
241
|
+
if len(x_coords_) != M:
|
|
242
|
+
raise ValueError(SHAPE_ERR2.format('x_coords', len(x_coords_),
|
|
243
|
+
'rows', M))
|
|
244
|
+
else:
|
|
245
|
+
x_coords_ = np.arange(M)
|
|
246
|
+
if y_coords is not None:
|
|
247
|
+
y_coords_ = np.asarray(y_coords)
|
|
248
|
+
if len(y_coords_) != N:
|
|
249
|
+
raise ValueError(SHAPE_ERR2.format('y_coords', len(y_coords_),
|
|
250
|
+
'columns', N))
|
|
251
|
+
else:
|
|
252
|
+
y_coords_ = np.arange(N)
|
|
253
|
+
# get the actual coordinates
|
|
254
|
+
x, y = np.meshgrid(x_coords_, y_coords_)
|
|
227
255
|
xv = x.T.ravel()
|
|
228
256
|
yv = y.T.ravel()
|
|
229
257
|
col_flat = dot_colours_arr.ravel()
|
|
@@ -79,7 +79,7 @@ def lollipop(values:np.ndarray, labels:np.ndarray,
|
|
|
79
79
|
ax:plt.Axes | None=None,
|
|
80
80
|
kwargs_lines_dict:dict[Any,Any] | None=None,
|
|
81
81
|
kwargs_plot_dict:dict[Any,Any] | None=None,
|
|
82
|
-
) -> tuple[plt.
|
|
82
|
+
) -> tuple[plt.Figure, plt.Axes]:
|
|
83
83
|
"""
|
|
84
84
|
Plots a lollipop chart.
|
|
85
85
|
|
|
@@ -960,7 +960,6 @@ class DecisionCurve(object):
|
|
|
960
960
|
self.NET_BENEFIT = results
|
|
961
961
|
self.CALCULATED=True
|
|
962
962
|
# \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
|
|
963
|
-
# NOTE add smoother paramter to allow for a different smoothing function.
|
|
964
963
|
def plot(self,
|
|
965
964
|
ax: plt.Axes | None = None,
|
|
966
965
|
col_dict: dict[str,str] | None = None,
|