plot-misc 2.2.1__py3-none-any.whl → 2.3.0__py3-none-any.whl

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/__init__.py CHANGED
@@ -1 +1,12 @@
1
+ """
2
+ plot-misc: matplotlib-based plotting archetypes for scientific figures.
3
+
4
+ A curated collection of user-oriented plotting functions and
5
+ classes built on top of `matplotlib`. Each function returns standard
6
+ matplotlib `Figure`/`Axes` objects, so results can be further customised
7
+ with familiar matplotlib methods. Per the package design callables are limited
8
+ to creating illustrations, and should data be internally calculated this is
9
+ done with options for user overwrites, while making the derived data available
10
+ for inspection and re-use.
11
+ """
1
12
  from ._version import __version__
plot_misc/_version.py CHANGED
@@ -1 +1 @@
1
- __version__ = '2.2.1'
1
+ __version__ = '2.3.0'
plot_misc/constants.py CHANGED
@@ -58,6 +58,8 @@ class UtilsNames(object):
58
58
  annot_pval = 'matrix_pvalue'
59
59
  annot_effect = 'matrix_point_estimate'
60
60
  value_point = 'curated_matrix_point_estimate_value'
61
+ value_unsigned_log = 'curated_matrix_value_unsigned_log'
62
+ value_raw = 'curated_matrix_value_raw'
61
63
  value_original = 'crude_point_estimate'
62
64
  source_data = 'source_data'
63
65
  mat_point = 'point'
@@ -67,8 +69,12 @@ class UtilsNames(object):
67
69
  mat_outcome = 'outcome'
68
70
  mat_exposure_list = ['IL2ra', 'IP10', 'SCF', 'TRAIL']
69
71
  mat_outcome_list = ['HDL-C', 'LDL-C']
72
+ mat_annot_symbol = 'symbol'
70
73
  mat_annot_star = 'star'
71
74
  mat_annot_pval = 'pvalues'
75
+ mat_annot_pval_signed = 'pvalues_signed'
76
+ mat_annot_pval_unsigned = 'pvalues_unsigned'
77
+ mat_annot_pval_raw = 'pvalues_raw'
72
78
  mat_annot_point = 'point_estimates'
73
79
  mat_annot_none = '`NoneType`'
74
80
  roc_false_positive = 'false_positive'
@@ -508,6 +508,54 @@ def heatmap_pvalue_matrix(**kwargs):
508
508
  data.index.name = UtilsNames.mat_outcome
509
509
  return data
510
510
 
511
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
512
+ @dataset
513
+ def qc_matrix(seed=2026):
514
+ """
515
+ Creates a dummy quality-control (QC) data set to showcase
516
+ `plot_misc.heatmap.masked_heatmap`.
517
+
518
+ The values are signed, standardised QC deviations for a set of samples
519
+ (rows) across several QC metrics (columns). The accompanying indicator
520
+ flags the cells that failed QC (an absolute deviation above 2), i.e. the
521
+ cells `masked_heatmap` should highlight; the passing cells are left to the
522
+ background layer.
523
+
524
+ Parameters
525
+ ----------
526
+ seed : `int`, default 2026
527
+ Seed for the random number generator, ensuring a reproducible matrix.
528
+
529
+ Returns
530
+ -------
531
+ values : `pd.DataFrame`
532
+ Signed standardised QC deviations of shape (12, 6).
533
+ indicator : `pd.DataFrame`
534
+ A binary (0/1) table of the same shape as `values`, equal to 1 where
535
+ the metric failed QC and 0 otherwise.
536
+ """
537
+ rng = np.random.default_rng(seed)
538
+ samples = ['Sample_{:02d}'.format(i) for i in range(1, 13)]
539
+ metrics = [
540
+ 'CallRate', 'Heterozygosity', 'Contamination', 'MeanDepth',
541
+ 'DuplicationRate', 'InsertSize',
542
+ ]
543
+ values = pd.DataFrame(
544
+ rng.normal(loc=0.0, scale=1.3, size=(len(samples), len(metrics))),
545
+ index=samples, columns=metrics,
546
+ )
547
+ # inject a handful of unambiguous QC failures so the showcase always has
548
+ # highlighted cells regardless of the random draw
549
+ values.iloc[0, 2] = 3.4
550
+ values.iloc[3, 0] = -3.1
551
+ values.iloc[5, 4] = 2.8
552
+ values.iloc[7, 1] = -2.6
553
+ values.iloc[9, 5] = 3.0
554
+ values.iloc[11, 3] = -2.9
555
+ values = values.round(3)
556
+ indicator = (values.abs() > 2).astype(int)
557
+ return values, indicator
558
+
511
559
  # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
512
560
  @dataset
513
561
  def load_calibration_data(**kwargs):
plot_misc/forest.py CHANGED
@@ -982,20 +982,6 @@ class EmpiricalSupport(object):
982
982
  results_ : `EmpiricalSupportResults`
983
983
  An EmpiricalSupportResults instance.
984
984
 
985
- Methods
986
- -------
987
- calc_empirical_support(estimate, standard_error, alpha)
988
- Computes the range of confidence intervals and compatibility metrics
989
- over the supplied alpha values.
990
-
991
- plot_tree(...)
992
- Creates a 'tree plot' summarising the parameter space supported by
993
- the data, with options for CI and estimate annotations.
994
-
995
- _plot_empirical_support(...)
996
- Generates a visualisation of confidence intervals and their overlap
997
- across varying alpha values.
998
-
999
985
  Notes
1000
986
  -----
1001
987
  This implementation is based on the concept of compatibility (or
plot_misc/heatmap.py CHANGED
@@ -11,6 +11,10 @@ heatmap(data, row_labels, col_labels, ...)
11
11
  Draws a standard heatmap using matplotlib's `imshow`, with options for
12
12
  gridlines, tick formatting, and embedded colourbars.
13
13
 
14
+ masked_heatmap(data, indicator, row_labels, col_labels, ...)
15
+ Draws a two-layer heatmap: a single-colour background and, on top of it,
16
+ the heatmap restricted to the cells flagged by a binary indicator table.
17
+
14
18
  annotate_heatmap(im, data=None, valfmt=None, ...)
15
19
  Adds text annotations to an existing heatmap image (AxesImage object),
16
20
  with configurable formatting and colour thresholding.
@@ -22,9 +26,8 @@ from the example published in the official matplotlib gallery [1]_.
22
26
 
23
27
  References
24
28
  ----------
25
- .. [1] Matplotlib contributors. "Creating annotated heatmaps."
26
- Matplotlib Gallery.
27
- https://matplotlib.org/stable/gallery/images_contours_and_fields/image_annotated_heatmap.html
29
+ .. [1] Matplotlib contributors. "Creating annotated heatmaps." Matplotlib
30
+ Gallery. https://matplotlib.org/stable/gallery/images_contours_and_fields/image_annotated_heatmap.html
28
31
  """
29
32
 
30
33
  # modules
@@ -32,9 +35,13 @@ import numpy as np
32
35
  import pandas as pd
33
36
  import matplotlib
34
37
  import matplotlib.pyplot as plt
38
+ from matplotlib.colors import ListedColormap
39
+ from matplotlib.patches import Rectangle
35
40
  from plot_misc.utils.utils import _update_kwargs
36
41
  from plot_misc.errors import (
37
42
  is_type,
43
+ is_df,
44
+ InputValidationError,
38
45
  )
39
46
  from plot_misc.constants import Real
40
47
  from typing import Any
@@ -45,6 +52,7 @@ def heatmap(data:pd.DataFrame | np.ndarray, row_labels:list[str] | np.ndarray,
45
52
  grid_linestyle:str='-', grid_linewidth:float=3,
46
53
  cbar_bool:bool=False, cbar_label:str="",
47
54
  ax:plt.Axes | None = None,
55
+ figsize:tuple[float,float] | None = None,
48
56
  grid_kw:dict[Any,Any] | None = None,
49
57
  cbar_kw:dict[Any,Any] | None = None,
50
58
  **kwargs:Any,
@@ -78,6 +86,8 @@ def heatmap(data:pd.DataFrame | np.ndarray, row_labels:list[str] | np.ndarray,
78
86
  ax : `plt.Axes` or `None`, default None
79
87
  A `matplotlib.axes.Axes` instance to which the heatmap is plotted. If
80
88
  not provided, use current axes or create a new one.
89
+ figsize : `tuple` [`float`, `float`] or `None`, default `None`
90
+ Figure size in inches (width, height). Ignored if `ax` is provided.
81
91
  grid_kw : `dict` [`str`,`any`] or `None`, default None
82
92
  A dictionary with arguments to `matplotlib.Axes.grid`.
83
93
  cbar_kw : `dict` [`str`, `any`] or `None`, default `None`
@@ -105,10 +115,20 @@ def heatmap(data:pd.DataFrame | np.ndarray, row_labels:list[str] | np.ndarray,
105
115
  Matplotlib Gallery.
106
116
  https://matplotlib.org/stable/gallery/images_contours_and_fields/image_annotated_heatmap.html
107
117
  """
108
-
118
+ # check in put
119
+ is_type(data, (pd.DataFrame, np.ndarray))
120
+ is_type(row_labels, (list, np.ndarray))
121
+ is_type(col_labels, (list, np.ndarray))
122
+ is_type(grid_col, str)
123
+ is_type(grid_linestyle, str)
124
+ is_type(grid_linewidth, Real)
125
+ is_type(cbar_bool, bool)
126
+ is_type(cbar_label, str)
109
127
  # create a axes if needed
110
- if not ax:
111
- ax = plt.gca()
128
+ if ax is None:
129
+ _, ax = plt.subplots(figsize=figsize)
130
+ else:
131
+ f = ax.figure
112
132
  # check input
113
133
  if isinstance(data, pd.DataFrame):
114
134
  matrix = data.copy().to_numpy()
@@ -117,10 +137,6 @@ def heatmap(data:pd.DataFrame | np.ndarray, row_labels:list[str] | np.ndarray,
117
137
  # copy
118
138
  row_lab = row_labels
119
139
  col_lab = col_labels
120
- # check additional input
121
- is_type(row_lab, (list, np.array))
122
- is_type(col_lab, (list, np.array))
123
- is_type(cbar_label, str)
124
140
  # map None to dict
125
141
  grid_kw = grid_kw or {}
126
142
  cbar_kw = cbar_kw or {}
@@ -156,12 +172,201 @@ def heatmap(data:pd.DataFrame | np.ndarray, row_labels:list[str] | np.ndarray,
156
172
  new_grid_kwargs = _update_kwargs(
157
173
  update_dict=grid_kw, which="minor", color=grid_col,
158
174
  linestyle=grid_linestyle, linewidth=grid_linewidth,
159
- )
175
+ clip_on=False,)
160
176
  ax.grid(**new_grid_kwargs)
161
177
  ax.tick_params(which="minor", bottom=False, left=False)
162
178
  # return stuff
163
179
  return im, cbar
164
180
 
181
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
182
+ def masked_heatmap(data:pd.DataFrame | np.ndarray,
183
+ indicator:pd.DataFrame | np.ndarray,
184
+ row_labels:list[str] | np.ndarray,
185
+ col_labels:list[str] | np.ndarray,
186
+ background_col:str='white', background_gridcol:str='white',
187
+ background_linestyle:str='-', background_linewidth:float=0.5,
188
+ background_zorder:Real = 1,
189
+ outline_col:str='black', outline_linestyle:str='-',
190
+ outline_linewidth:float=1.5, outline_zorder:Real = 2,
191
+ frame: bool=False,
192
+ cbar_bool:bool=False, cbar_label:str="",
193
+ ax:plt.Axes | None = None,
194
+ figsize:tuple[float,float] | None = None,
195
+ grid_kw:dict[Any,Any] | None = None,
196
+ cbar_kw:dict[Any,Any] | None = None,
197
+ background_kw:dict[Any,Any] | None = None,
198
+ outline_kw:dict[Any,Any] | None = None,
199
+ **kwargs: Any,
200
+ ) -> tuple[matplotlib.image.AxesImage,
201
+ matplotlib.colorbar.Colorbar]:
202
+ """
203
+ Plot a two-layer heatmap masked by a binary indicator table.
204
+
205
+ The function draws two layers. First a single-colour background covering
206
+ every cell (carrying an optional grid lattice). Second, the heatmap of
207
+ `data`, restricted to the cells where `indicator` equals 1.
208
+
209
+ Parameters
210
+ ----------
211
+ data : `pd.DataFrame` or `np.ndarray`
212
+ A 2D array of shape (M, N) containing the values to plot.
213
+ indicator : `pd.DataFrame` or `np.ndarray`
214
+ A binary (0/1, booleans accepted) array of the same shape as `data`.
215
+ Only cells equal to 1 are drawn and outlined.
216
+ row_labels : `list` [`str`] or `np.ndarray`
217
+ A list or array of length M with the labels for the rows.
218
+ col_labels : `list` [`str`] or `np.ndarray`
219
+ A list or array of length N with the labels for the columns.
220
+ background_col : `str`, default 'white'
221
+ The fill colour of the background layer.
222
+ background_gridcol : `str`, default 'white'
223
+ The colour of the background grid lattice lines.
224
+ background_linestyle : `str`, default '-'
225
+ The linestyle of the background grid lattice.
226
+ background_linewidth : `float`, default 0.5
227
+ The width of the background grid lattice. Set to 0 to suppress it.
228
+ background_zorder : `int`, `float` default `1`
229
+ The draw order of the background grid lattice.
230
+ outline_col : `str`, default 'black'
231
+ The edge colour of the per-cell outlines drawn on `indicator == 1`
232
+ cells.
233
+ outline_linestyle : `str`, default '-'
234
+ The linestyle of the per-cell outlines.
235
+ outline_linewidth : `float`, default 1.5
236
+ The width of the per-cell outlines. Set to 0 to suppress them.
237
+ outline_zorder : `int`, `float`, default `2`
238
+ The draw order of the per-cell outlines.
239
+ frame : `bool`, default `False`
240
+ Whether to plot the spines.
241
+ cbar_bool : `bool`, default `False`
242
+ If `True`, add a colourbar (built from the masked heatmap layer).
243
+ cbar_label : `str`, default ""
244
+ The label for the colourbar.
245
+ ax : `plt.Axes` or `None`, default `None`
246
+ A `matplotlib.axes.Axes` instance to draw on. If `None`, a new figure
247
+ and axes are created.
248
+ figsize : `tuple` [`float`, `float`] or `None`, default `None`
249
+ Figure size in inches (width, height). Ignored if `ax` is provided.
250
+ grid_kw : `dict` [`str`, `any`] or `None`, default `None`
251
+ Additional arguments forwarded to `matplotlib.Axes.grid` for the
252
+ background lattice.
253
+ outline_kw : `dict` [`str`, `any`] or `None`, default `None`
254
+ Additional arguments forwarded to each `matplotlib.patches.Rectangle`
255
+ outline. Outlines default to `clip_on=False` so the borders of cells on
256
+ the matrix boundary are not clipped by the axes edge; pass
257
+ `{'clip_on': True}` to restore clipping.
258
+ cbar_kw : `dict` [`str`, `any`] or `None`, default `None`
259
+ A dictionary with arguments to `matplotlib.Figure.colorbar`.
260
+ background_kw : `dict` [`str`, `any`] or `None`, default `None`,
261
+ A dictionary with arguments to `heatmap.heatmap`.
262
+ **kwargs : `any`,
263
+ All other arguments passed to `masking ax.imshow`.
264
+
265
+ Returns
266
+ -------
267
+ im : `matplotlib.image.AxesImage`
268
+ The masked (foreground) heatmap image object.
269
+ cbar : `matplotlib.colorbar.Colorbar` or `None`
270
+ The colourbar object if `cbar_bool` is `True`, otherwise `None`.
271
+
272
+ Notes
273
+ -----
274
+ The masking is achieved by a separate imshow call setting the cells to
275
+ transparent, revealing the background.
276
+
277
+ The returned `im` mirrors the contract of `heatmap` and can therefore be
278
+ annotated using `annotate_heatmap`.
279
+ """
280
+ # create an axes if needed
281
+ if ax is None:
282
+ _, ax = plt.subplots(figsize=figsize)
283
+ else:
284
+ f = ax.figure
285
+ # check input types
286
+ is_type(data, (pd.DataFrame, np.ndarray))
287
+ is_type(indicator, (pd.DataFrame, np.ndarray))
288
+ _ = [is_type(k, (dict, type(None))) for k in\
289
+ (grid_kw, cbar_kw, outline_kw, background_kw)]
290
+ # the indicator must match the data shape exactly (full 2D shape, not just
291
+ # the row count)
292
+ if np.shape(data) != np.shape(indicator):
293
+ raise InputValidationError(
294
+ f"`indicator` shape {np.shape(indicator)} does not match `data` "
295
+ f"shape {np.shape(data)}."
296
+ )
297
+ # coerce the data and indicator to numpy arrays
298
+ if isinstance(data, pd.DataFrame):
299
+ matrix = data.copy().to_numpy()
300
+ else:
301
+ matrix = data
302
+ if isinstance(indicator, pd.DataFrame):
303
+ flag = indicator.copy().to_numpy()
304
+ else:
305
+ flag = indicator
306
+ # flag should only contain 0 and 1
307
+ unique_flags = set(np.unique(flag).tolist())
308
+ if not unique_flags.issubset({0, 1}):
309
+ raise InputValidationError(
310
+ f"`indicator` must only contain binary (0/1) values, got "
311
+ f"{sorted(unique_flags)}."
312
+ )
313
+ # setup the kwargs None to dict
314
+ background_kw = background_kw or {}
315
+ # masking_kw = masking_kw or {}
316
+ grid_kw = grid_kw or {}
317
+ cbar_kw = cbar_kw or {}
318
+ outline_kw = outline_kw or {}
319
+ outline_kw = _update_kwargs(update_dict=outline_kw,
320
+ zorder=outline_zorder)
321
+ # the background grid lattice carries the background draw order
322
+ grid_kw = _update_kwargs(update_dict=grid_kw, zorder=background_zorder)
323
+ # ### Layer 1: a single-colour background covering every cell. Reusing
324
+ # `heatmap` keeps a single source of truth for the tick, label, spine and
325
+ # grid (lattice) cosmetics.
326
+ background = np.zeros_like(matrix, dtype=float)
327
+ layer1_kwargs = _update_kwargs(
328
+ update_dict=background_kw,
329
+ data=background, row_labels=row_labels, col_labels=col_labels,
330
+ grid_col=background_gridcol, grid_linestyle=background_linestyle,
331
+ grid_linewidth=background_linewidth, cbar_bool=False, ax=ax,
332
+ grid_kw=grid_kw, cmap=ListedColormap([background_col]),
333
+ )
334
+ heatmap(**layer1_kwargs, )
335
+ # ### Layer 2: the heatmap, masked so only `indicator == 1` cells are drawn.
336
+ masked = np.ma.masked_where(flag == 0, matrix)
337
+ # creating an alpha matrix.
338
+ # user_alpha = masking_kw.pop('alpha', 1.0)
339
+ user_alpha = kwargs.pop('alpha', 1.0)
340
+ alpha = (flag == 1).astype(float) * np.asarray(user_alpha, dtype=float)
341
+ layer2_kwargs = _update_kwargs(
342
+ update_dict=kwargs, alpha=alpha,
343
+ )
344
+ im = ax.imshow(masked, **layer2_kwargs)
345
+ # Create colorbar from the foreground (masked) layer
346
+ if cbar_bool:
347
+ cbar = ax.figure.colorbar(im, ax=ax, **cbar_kw)
348
+ cbar.ax.set_ylabel(cbar_label, rotation=-90, va="bottom")
349
+ else:
350
+ cbar = None
351
+ # ### Outline each `indicator == 1` cell. Zero cells get no patch, so they
352
+ # carry no outline; a zero `outline_linewidth` hides the borders.
353
+ rect_kw = _update_kwargs(update_dict=outline_kw, facecolor='none',
354
+ edgecolor=outline_col,
355
+ linestyle=outline_linestyle,
356
+ linewidth=outline_linewidth,
357
+ clip_on=False,
358
+ )
359
+ rows, cols = np.where(flag == 1)
360
+ # NOTE the 0.5 and 1.0 are imshow fixed convention and should be hardcoded
361
+ for i, j in zip(rows, cols):
362
+ ax.add_patch(Rectangle((j-.5, i-.5), 1, 1, **rect_kw))
363
+ # Show the spines
364
+ if frame:
365
+ for spine in ax.spines.values():
366
+ spine.set_visible(True)
367
+ # return stuff
368
+ return im, cbar
369
+
165
370
  # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
166
371
  def annotate_heatmap(
167
372
  im:plt.Axes.imshow,
@@ -210,6 +415,10 @@ def annotate_heatmap(
210
415
 
211
416
  # mapping data to matrix
212
417
  values = im.get_array()
418
+ # masked cells (e.g. from `masked_heatmap`) are not drawn and must not be
419
+ # annotated; `getmaskarray` yields a full boolean mask for masked arrays and
420
+ # an all-False mask for plain arrays, leaving the unmasked path unchanged
421
+ mask = np.ma.getmaskarray(values)
213
422
  if data is None:
214
423
  matrix = im.get_array()
215
424
  elif isinstance(data, pd.DataFrame):
@@ -239,6 +448,9 @@ def annotate_heatmap(
239
448
  texts = []
240
449
  for i in range(matrix.shape[0]):
241
450
  for j in range(matrix.shape[1]):
451
+ # skip masked cells, which carry no drawn value to annotate
452
+ if mask[i, j]:
453
+ continue
242
454
  # only run if threshold exists
243
455
  if threshold is not None:
244
456
  kw.update(color=textcolors[int(abs(values[i, j]) >= threshold)])
@@ -55,8 +55,13 @@ from typing import (
55
55
  Any,
56
56
  Callable,
57
57
  Union,
58
- Self,
59
58
  )
59
+ # `typing.Self` was added in Python 3.11; fall back to typing_extensions on 3.10
60
+ # (the minimum supported version per pyproject `requires-python`).
61
+ if sys.version_info >= (3, 11):
62
+ from typing import Self
63
+ else:
64
+ from typing_extensions import Self
60
65
  from statsmodels.nonparametric.smoothers_lowess import lowess
61
66
  # from packaging import version
62
67
  # if version.parse('3.4.0') < version.parse(mpl._version.version):
@@ -665,15 +670,6 @@ class DecisionCurve(object):
665
670
  include at least one predicted risk score (between 0 and 1) and a
666
671
  binary outcome variable.
667
672
 
668
- Methods
669
- -------
670
- calc_net_benefit(...)
671
- Computes the net benefit across a range of thresholds for one or more
672
- models.
673
- plot(...)
674
- Visualises the decision curves, with optional smoothing and style
675
- customisation.
676
-
677
673
  Notes
678
674
  -----
679
675
  This implementation is adapted from the `dcurves` Python package
@@ -763,8 +759,8 @@ class DecisionCurve(object):
763
759
  These rates are scaled by the assumed prevalence to allow valid
764
760
  comparisons across populations with different case/control ratios.
765
761
 
766
- Code adapted from
767
- `here <https://github.com/MSKCC-Epi-Bio/dcurves/blob/main/dcurves/dca.py>`_.
762
+ Code adapted from the
763
+ `dcurves true/false rate calculation <https://github.com/MSKCC-Epi-Bio/dcurves/blob/main/dcurves/dca.py>`_.
768
764
 
769
765
  Hash: 007c64b
770
766
  """
@@ -861,8 +857,8 @@ class DecisionCurve(object):
861
857
 
862
858
  The resulting table can be visualised using the `plot()` method.
863
859
 
864
- Code adapted from:
865
- `here <https://github.com/MSKCC-Epi-Bio/dcurves/blob/main/dcurves/dca.py>`_
860
+ Code adapted from the
861
+ `dcurves net benefit calculation <https://github.com/MSKCC-Epi-Bio/dcurves/blob/main/dcurves/dca.py>`_
866
862
 
867
863
  Hash: 007c64b
868
864
  """
plot_misc/survival.py CHANGED
@@ -292,6 +292,7 @@ def extract_follow_up(data: pd.DataFrame,
292
292
  -------
293
293
  pd.DataFrame
294
294
  DataFrame with the following columns:
295
+
295
296
  - 'time': Requested time points (as integers)
296
297
  - '{output_col}_at_risk': Number at risk at each time point
297
298
  - '{output_col}_at_risk_format': Formatted at-risk numbers with
@@ -16,7 +16,7 @@ format_estimates(point, se=None, lower=None, upper=None, alpha=0.05, ...)
16
16
  sci_notation(number, sig_fig=2, ...)
17
17
  Converts a float into scientific notation with superscript exponents.
18
18
 
19
- format_roc(observed, predicted, **kwargs)
19
+ format_roc(observed, predicted, ...)
20
20
  Computes ROC curve data and returns it as a tidy DataFrame.
21
21
 
22
22
  string_interval(limits, int_notation, middle, lower_lim, inq_space, sep)