tombolo.plots

  1import re
  2
  3import jsonschema
  4import matplotlib.pyplot as plt
  5
  6from ._utils import _grid, _table, _forest, _barh
  7
  8
  9def ranking_plot(data: dict) -> plt.Figure:
 10    """Horizontal bar chart of treatment rankings.
 11
 12    Parameters:
 13    - `data`: Result dict from `tombolo.nma` or `tombolo.bnma`. Only `ranking` is used.
 14
 15    Returns treatments sorted by rank score (P-score for NMA, SUCRA for BNMA).
 16    """
 17    _schema = {
 18        "type": "object",
 19        "required": ["ranking"],
 20        "properties": {
 21            "ranking": {
 22                "type": "object",
 23                "additionalProperties": {"type": "number", "minimum": 0, "maximum": 1},
 24            }
 25        },
 26    }
 27    jsonschema.validate(instance=data, schema=_schema)
 28    return _barh(data["ranking"])
 29
 30
 31def league_table(data: dict) -> plt.Figure:
 32    """Grid of pairwise treatment comparisons.
 33
 34    Parameters:
 35    - `data`: Result dict from `tombolo.nma` or `tombolo.bnma`. Only `league` is used.
 36
 37    Each cell shows the mean difference and confidence (or credible) interval for the row
 38    treatment relative to the column treatment. Diagonal cells show the treatment name.
 39    P-values are included for NMA results.
 40    """
 41    _matrix = {
 42        "type": "object",
 43        "additionalProperties": {
 44            "type": "object",
 45            "additionalProperties": {"type": ["number", "null"]},
 46        },
 47    }
 48
 49    _schema = {
 50        "type": "object",
 51        "required": ["league"],
 52        "properties": {
 53            "league": {
 54                "type": "object",
 55                "required": ["md", "lower", "upper"],
 56                "properties": {
 57                    "md": _matrix,
 58                    "lower": _matrix,
 59                    "upper": _matrix,
 60                    "pval": _matrix,
 61                },
 62            }
 63        },
 64    }
 65
 66    jsonschema.validate(instance=data, schema=_schema)
 67    return _grid(data["league"])
 68
 69
 70def heterogeneity_table(data: dict) -> plt.Figure:
 71    """Summary table of heterogeneity statistics.
 72
 73    Parameters:
 74    - `data`: Result dict from `tombolo.nma` or `tombolo.bnma`. Only `heterogeneity` is used.
 75
 76    For NMA results: Q statistic, p-value, I², and τ.
 77    For BNMA results: posterior SD and 95% credible interval.
 78    """
 79    _nma_heterogeneity = {
 80        "type": "object",
 81        "required": ["tau2", "tau", "i2", "i2_lower", "i2_upper", "q", "q_df", "q_pval"],
 82        "properties": {
 83            "tau2": {"type": "number", "minimum": 0},
 84            "tau": {"type": "number", "minimum": 0},
 85            "i2": {"type": "number", "minimum": 0, "maximum": 1},
 86            "i2_lower": {"type": "number", "minimum": 0, "maximum": 1},
 87            "i2_upper": {"type": "number", "minimum": 0, "maximum": 1},
 88            "q": {"type": "number", "minimum": 0},
 89            "q_df": {"type": "integer", "minimum": 0},
 90            "q_pval": {"type": "number", "minimum": 0, "maximum": 1},
 91        },
 92    }
 93
 94    _bnma_heterogeneity = {
 95        "type": "object",
 96        "required": ["sd", "sd_lower", "sd_upper"],
 97        "properties": {
 98            "sd": {"type": "number", "minimum": 0},
 99            "sd_lower": {"type": "number", "minimum": 0},
100            "sd_upper": {"type": "number", "minimum": 0},
101        },
102    }
103
104    _schema = {
105        "type": "object",
106        "required": ["heterogeneity"],
107        "properties": {
108            "heterogeneity": {"oneOf": [_nma_heterogeneity, _bnma_heterogeneity]}
109        },
110    }
111
112    jsonschema.validate(instance=data, schema=_schema)
113    return _table(data["heterogeneity"])
114
115
116def forest_plot(data: dict, reference: str) -> plt.Figure:
117    """Forest plot of all treatments relative to a reference.
118
119    Parameters:
120    - `data`: Result dict from `tombolo.nma` or `tombolo.bnma`. Only `league` is used.
121    - `reference`: Name of the reference treatment. All other treatments are plotted
122      relative to it, sorted by effect size. Non-alphanumeric characters are normalized to underscores.
123
124    Returns mean differences and confidence (or credible) intervals for each treatment
125    versus the reference. P-values are included for NMA results.
126
127    Raises `RuntimeError` if `reference` is not found in the data.
128    """
129    _matrix = {
130        "type": "object",
131        "additionalProperties": {
132            "type": "object",
133            "additionalProperties": {"type": ["number", "null"]},
134        },
135    }
136
137    _schema = {
138        "type": "object",
139        "required": ["league"],
140        "properties": {
141            "league": {
142                "type": "object",
143                "required": ["md", "lower", "upper"],
144                "properties": {
145                    "md": _matrix,
146                    "lower": _matrix,
147                    "upper": _matrix,
148                    "pval": _matrix,
149                },
150            }
151        },
152    }
153
154    jsonschema.validate(instance=data, schema=_schema)
155    ref = re.sub(r"[^A-Za-z0-9_]", "_", reference)
156    if ref not in data["league"]["md"]:
157        raise RuntimeError("Missing reference")
158    
159    label = "[95% CI]" if "pval" in data["league"] else "[95% CrI]"
160    return _forest(data["league"], ref, interval_label=label)
161
162
163def prediction_table(data: dict) -> plt.Figure:
164    """Grid of prediction intervals. Only applicable to NMA results.
165
166    Parameters:
167    - `data`: Result dict from `tombolo.nma`. Only `prediction` is used.
168
169    Each cell shows the 95% prediction interval for the row treatment relative to the column treatment.
170    """
171    _matrix = {
172        "type": "object",
173        "additionalProperties": {
174            "type": "object",
175            "additionalProperties": {"type": ["number", "null"]},
176        },
177    }
178
179    _schema = {
180        "type": "object",
181        "required": ["prediction"],
182        "properties": {
183            "prediction": {
184                "type": "object",
185                "required": ["lower", "upper"],
186                "properties": {"lower": _matrix, "upper": _matrix},
187            }
188        },
189    }
190
191    jsonschema.validate(instance=data, schema=_schema)
192    return _grid(data["prediction"])
193
194
195def convergence_table(data: dict) -> plt.Figure:
196    """Summary table of MCMC convergence diagnostics. Only applicable to BNMA results.
197
198    Parameters:
199    - `data`: Result dict from `tombolo.bnma`. Only `convergence` is used.
200
201    Returns R̂ (max), ESS bulk (min), and ESS tail (min) across all model parameters.
202    """
203    _schema = {
204        "type": "object",
205        "required": ["convergence"],
206        "properties": {
207            "convergence": {
208                "type": "object",
209                "required": ["rhat_max", "ess_bulk_min", "ess_tail_min"],
210                "properties": {
211                    "rhat_max": {"type": "number"},
212                    "ess_bulk_min": {"type": "number"},
213                    "ess_tail_min": {"type": "number"},
214                },
215            }
216        },
217    }
218    jsonschema.validate(instance=data, schema=_schema)
219    return _table(data["convergence"])
def ranking_plot(data: dict) -> matplotlib.figure.Figure:
10def ranking_plot(data: dict) -> plt.Figure:
11    """Horizontal bar chart of treatment rankings.
12
13    Parameters:
14    - `data`: Result dict from `tombolo.nma` or `tombolo.bnma`. Only `ranking` is used.
15
16    Returns treatments sorted by rank score (P-score for NMA, SUCRA for BNMA).
17    """
18    _schema = {
19        "type": "object",
20        "required": ["ranking"],
21        "properties": {
22            "ranking": {
23                "type": "object",
24                "additionalProperties": {"type": "number", "minimum": 0, "maximum": 1},
25            }
26        },
27    }
28    jsonschema.validate(instance=data, schema=_schema)
29    return _barh(data["ranking"])

Horizontal bar chart of treatment rankings.

Parameters:

Returns treatments sorted by rank score (P-score for NMA, SUCRA for BNMA).

def league_table(data: dict) -> matplotlib.figure.Figure:
32def league_table(data: dict) -> plt.Figure:
33    """Grid of pairwise treatment comparisons.
34
35    Parameters:
36    - `data`: Result dict from `tombolo.nma` or `tombolo.bnma`. Only `league` is used.
37
38    Each cell shows the mean difference and confidence (or credible) interval for the row
39    treatment relative to the column treatment. Diagonal cells show the treatment name.
40    P-values are included for NMA results.
41    """
42    _matrix = {
43        "type": "object",
44        "additionalProperties": {
45            "type": "object",
46            "additionalProperties": {"type": ["number", "null"]},
47        },
48    }
49
50    _schema = {
51        "type": "object",
52        "required": ["league"],
53        "properties": {
54            "league": {
55                "type": "object",
56                "required": ["md", "lower", "upper"],
57                "properties": {
58                    "md": _matrix,
59                    "lower": _matrix,
60                    "upper": _matrix,
61                    "pval": _matrix,
62                },
63            }
64        },
65    }
66
67    jsonschema.validate(instance=data, schema=_schema)
68    return _grid(data["league"])

Grid of pairwise treatment comparisons.

Parameters:

Each cell shows the mean difference and confidence (or credible) interval for the row treatment relative to the column treatment. Diagonal cells show the treatment name. P-values are included for NMA results.

def heterogeneity_table(data: dict) -> matplotlib.figure.Figure:
 71def heterogeneity_table(data: dict) -> plt.Figure:
 72    """Summary table of heterogeneity statistics.
 73
 74    Parameters:
 75    - `data`: Result dict from `tombolo.nma` or `tombolo.bnma`. Only `heterogeneity` is used.
 76
 77    For NMA results: Q statistic, p-value, I², and τ.
 78    For BNMA results: posterior SD and 95% credible interval.
 79    """
 80    _nma_heterogeneity = {
 81        "type": "object",
 82        "required": ["tau2", "tau", "i2", "i2_lower", "i2_upper", "q", "q_df", "q_pval"],
 83        "properties": {
 84            "tau2": {"type": "number", "minimum": 0},
 85            "tau": {"type": "number", "minimum": 0},
 86            "i2": {"type": "number", "minimum": 0, "maximum": 1},
 87            "i2_lower": {"type": "number", "minimum": 0, "maximum": 1},
 88            "i2_upper": {"type": "number", "minimum": 0, "maximum": 1},
 89            "q": {"type": "number", "minimum": 0},
 90            "q_df": {"type": "integer", "minimum": 0},
 91            "q_pval": {"type": "number", "minimum": 0, "maximum": 1},
 92        },
 93    }
 94
 95    _bnma_heterogeneity = {
 96        "type": "object",
 97        "required": ["sd", "sd_lower", "sd_upper"],
 98        "properties": {
 99            "sd": {"type": "number", "minimum": 0},
100            "sd_lower": {"type": "number", "minimum": 0},
101            "sd_upper": {"type": "number", "minimum": 0},
102        },
103    }
104
105    _schema = {
106        "type": "object",
107        "required": ["heterogeneity"],
108        "properties": {
109            "heterogeneity": {"oneOf": [_nma_heterogeneity, _bnma_heterogeneity]}
110        },
111    }
112
113    jsonschema.validate(instance=data, schema=_schema)
114    return _table(data["heterogeneity"])

Summary table of heterogeneity statistics.

Parameters:

For NMA results: Q statistic, p-value, I², and τ. For BNMA results: posterior SD and 95% credible interval.

def forest_plot(data: dict, reference: str) -> matplotlib.figure.Figure:
117def forest_plot(data: dict, reference: str) -> plt.Figure:
118    """Forest plot of all treatments relative to a reference.
119
120    Parameters:
121    - `data`: Result dict from `tombolo.nma` or `tombolo.bnma`. Only `league` is used.
122    - `reference`: Name of the reference treatment. All other treatments are plotted
123      relative to it, sorted by effect size. Non-alphanumeric characters are normalized to underscores.
124
125    Returns mean differences and confidence (or credible) intervals for each treatment
126    versus the reference. P-values are included for NMA results.
127
128    Raises `RuntimeError` if `reference` is not found in the data.
129    """
130    _matrix = {
131        "type": "object",
132        "additionalProperties": {
133            "type": "object",
134            "additionalProperties": {"type": ["number", "null"]},
135        },
136    }
137
138    _schema = {
139        "type": "object",
140        "required": ["league"],
141        "properties": {
142            "league": {
143                "type": "object",
144                "required": ["md", "lower", "upper"],
145                "properties": {
146                    "md": _matrix,
147                    "lower": _matrix,
148                    "upper": _matrix,
149                    "pval": _matrix,
150                },
151            }
152        },
153    }
154
155    jsonschema.validate(instance=data, schema=_schema)
156    ref = re.sub(r"[^A-Za-z0-9_]", "_", reference)
157    if ref not in data["league"]["md"]:
158        raise RuntimeError("Missing reference")
159    
160    label = "[95% CI]" if "pval" in data["league"] else "[95% CrI]"
161    return _forest(data["league"], ref, interval_label=label)

Forest plot of all treatments relative to a reference.

Parameters:

  • data: Result dict from tombolo.nma or tombolo.bnma. Only league is used.
  • reference: Name of the reference treatment. All other treatments are plotted relative to it, sorted by effect size. Non-alphanumeric characters are normalized to underscores.

Returns mean differences and confidence (or credible) intervals for each treatment versus the reference. P-values are included for NMA results.

Raises RuntimeError if reference is not found in the data.

def prediction_table(data: dict) -> matplotlib.figure.Figure:
164def prediction_table(data: dict) -> plt.Figure:
165    """Grid of prediction intervals. Only applicable to NMA results.
166
167    Parameters:
168    - `data`: Result dict from `tombolo.nma`. Only `prediction` is used.
169
170    Each cell shows the 95% prediction interval for the row treatment relative to the column treatment.
171    """
172    _matrix = {
173        "type": "object",
174        "additionalProperties": {
175            "type": "object",
176            "additionalProperties": {"type": ["number", "null"]},
177        },
178    }
179
180    _schema = {
181        "type": "object",
182        "required": ["prediction"],
183        "properties": {
184            "prediction": {
185                "type": "object",
186                "required": ["lower", "upper"],
187                "properties": {"lower": _matrix, "upper": _matrix},
188            }
189        },
190    }
191
192    jsonschema.validate(instance=data, schema=_schema)
193    return _grid(data["prediction"])

Grid of prediction intervals. Only applicable to NMA results.

Parameters:

  • data: Result dict from tombolo.nma. Only prediction is used.

Each cell shows the 95% prediction interval for the row treatment relative to the column treatment.

def convergence_table(data: dict) -> matplotlib.figure.Figure:
196def convergence_table(data: dict) -> plt.Figure:
197    """Summary table of MCMC convergence diagnostics. Only applicable to BNMA results.
198
199    Parameters:
200    - `data`: Result dict from `tombolo.bnma`. Only `convergence` is used.
201
202    Returns R̂ (max), ESS bulk (min), and ESS tail (min) across all model parameters.
203    """
204    _schema = {
205        "type": "object",
206        "required": ["convergence"],
207        "properties": {
208            "convergence": {
209                "type": "object",
210                "required": ["rhat_max", "ess_bulk_min", "ess_tail_min"],
211                "properties": {
212                    "rhat_max": {"type": "number"},
213                    "ess_bulk_min": {"type": "number"},
214                    "ess_tail_min": {"type": "number"},
215                },
216            }
217        },
218    }
219    jsonschema.validate(instance=data, schema=_schema)
220    return _table(data["convergence"])

Summary table of MCMC convergence diagnostics. Only applicable to BNMA results.

Parameters:

  • data: Result dict from tombolo.bnma. Only convergence is used.

Returns R̂ (max), ESS bulk (min), and ESS tail (min) across all model parameters.