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`.
 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`.
 36
 37    Each cell shows the mean difference and confidence (or credible) interval for the row
 38    treatment relative to the column treatment. The contrast is row minus column. Diagonal
 39    cells show the treatment name. 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`.
 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": [
 82            "tau2",
 83            "tau",
 84            "i2",
 85            "i2_lower",
 86            "i2_upper",
 87            "q",
 88            "q_df",
 89            "q_pval",
 90        ],
 91        "properties": {
 92            "tau2": {"type": "number", "minimum": 0},
 93            "tau": {"type": "number", "minimum": 0},
 94            "i2": {"type": "number", "minimum": 0, "maximum": 1},
 95            "i2_lower": {"type": "number", "minimum": 0, "maximum": 1},
 96            "i2_upper": {"type": "number", "minimum": 0, "maximum": 1},
 97            "q": {"type": "number", "minimum": 0},
 98            "q_df": {"type": "integer", "minimum": 0},
 99            "q_pval": {"type": "number", "minimum": 0, "maximum": 1},
100        },
101    }
102
103    bnma_heterogeneity = {
104        "type": "object",
105        "required": ["sd", "sd_lower", "sd_upper"],
106        "properties": {
107            "sd": {"type": "number", "minimum": 0},
108            "sd_lower": {"type": "number", "minimum": 0},
109            "sd_upper": {"type": "number", "minimum": 0},
110        },
111    }
112
113    schema = {
114        "type": "object",
115        "required": ["heterogeneity"],
116        "properties": {
117            "heterogeneity": {"oneOf": [nma_heterogeneity, bnma_heterogeneity]}
118        },
119    }
120
121    jsonschema.validate(instance=data, schema=schema)
122    return _table(data["heterogeneity"])
123
124
125def forest_plot(data: dict, reference: str) -> plt.Figure:
126    """Forest plot of all treatments relative to a reference.
127
128    Parameters:
129    - `data`: Result dict from `tombolo.nma` or `tombolo.bnma`.
130    - `reference`: Name of the reference treatment. All other treatments are plotted
131      relative to it, sorted by effect size. Non-alphanumeric characters are normalized to underscores.
132
133    Returns mean differences and confidence (or credible) intervals for each treatment
134    versus the reference. P-values are included for NMA results.
135
136    Raises `RuntimeError` if `reference` is not found in the data.
137    """
138    matrix = {
139        "type": "object",
140        "additionalProperties": {
141            "type": "object",
142            "additionalProperties": {"type": ["number", "null"]},
143        },
144    }
145
146    schema = {
147        "type": "object",
148        "required": ["league"],
149        "properties": {
150            "league": {
151                "type": "object",
152                "required": ["md", "lower", "upper"],
153                "properties": {
154                    "md": matrix,
155                    "lower": matrix,
156                    "upper": matrix,
157                    "pval": matrix,
158                },
159            }
160        },
161    }
162
163    jsonschema.validate(instance=data, schema=schema)
164    ref = re.sub(r"[^A-Za-z0-9_]", "_", reference)
165    if ref not in data["league"]["md"]:
166        raise RuntimeError("Missing reference")
167
168    label = "[95% CI]" if "pval" in data["league"] else "[95% CrI]"
169    return _forest(data["league"], ref, interval_label=label)
170
171
172def prediction_table(data: dict) -> plt.Figure:
173    """Grid of prediction intervals. Only applicable to NMA results.
174
175    Parameters:
176    - `data`: Result dict from `tombolo.nma`.
177
178    Each cell shows the 95% prediction interval for the row treatment relative to the column treatment.
179    """
180    matrix = {
181        "type": "object",
182        "additionalProperties": {
183            "type": "object",
184            "additionalProperties": {"type": ["number", "null"]},
185        },
186    }
187
188    schema = {
189        "type": "object",
190        "required": ["prediction"],
191        "properties": {
192            "prediction": {
193                "type": "object",
194                "required": ["lower", "upper"],
195                "properties": {"lower": matrix, "upper": matrix},
196            }
197        },
198    }
199
200    jsonschema.validate(instance=data, schema=schema)
201    return _grid(data["prediction"])
202
203
204def convergence_table(data: dict) -> plt.Figure:
205    """Summary table of MCMC convergence diagnostics. Only applicable to BNMA results.
206
207    Parameters:
208    - `data`: Result dict from `tombolo.bnma`.
209
210    Returns R-hat (max), ESS bulk (min), and ESS tail (min) across all model parameters.
211    """
212    schema = {
213        "type": "object",
214        "required": ["convergence"],
215        "properties": {
216            "convergence": {
217                "type": "object",
218                "required": ["rhat_max", "ess_bulk_min", "ess_tail_min"],
219                "properties": {
220                    "rhat_max": {"type": "number"},
221                    "ess_bulk_min": {"type": "number"},
222                    "ess_tail_min": {"type": "number"},
223                },
224            }
225        },
226    }
227    jsonschema.validate(instance=data, schema=schema)
228    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`.
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`.
37
38    Each cell shows the mean difference and confidence (or credible) interval for the row
39    treatment relative to the column treatment. The contrast is row minus column. Diagonal
40    cells show the treatment name. 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. The contrast is row minus column. 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`.
 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": [
 83            "tau2",
 84            "tau",
 85            "i2",
 86            "i2_lower",
 87            "i2_upper",
 88            "q",
 89            "q_df",
 90            "q_pval",
 91        ],
 92        "properties": {
 93            "tau2": {"type": "number", "minimum": 0},
 94            "tau": {"type": "number", "minimum": 0},
 95            "i2": {"type": "number", "minimum": 0, "maximum": 1},
 96            "i2_lower": {"type": "number", "minimum": 0, "maximum": 1},
 97            "i2_upper": {"type": "number", "minimum": 0, "maximum": 1},
 98            "q": {"type": "number", "minimum": 0},
 99            "q_df": {"type": "integer", "minimum": 0},
100            "q_pval": {"type": "number", "minimum": 0, "maximum": 1},
101        },
102    }
103
104    bnma_heterogeneity = {
105        "type": "object",
106        "required": ["sd", "sd_lower", "sd_upper"],
107        "properties": {
108            "sd": {"type": "number", "minimum": 0},
109            "sd_lower": {"type": "number", "minimum": 0},
110            "sd_upper": {"type": "number", "minimum": 0},
111        },
112    }
113
114    schema = {
115        "type": "object",
116        "required": ["heterogeneity"],
117        "properties": {
118            "heterogeneity": {"oneOf": [nma_heterogeneity, bnma_heterogeneity]}
119        },
120    }
121
122    jsonschema.validate(instance=data, schema=schema)
123    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:
126def forest_plot(data: dict, reference: str) -> plt.Figure:
127    """Forest plot of all treatments relative to a reference.
128
129    Parameters:
130    - `data`: Result dict from `tombolo.nma` or `tombolo.bnma`.
131    - `reference`: Name of the reference treatment. All other treatments are plotted
132      relative to it, sorted by effect size. Non-alphanumeric characters are normalized to underscores.
133
134    Returns mean differences and confidence (or credible) intervals for each treatment
135    versus the reference. P-values are included for NMA results.
136
137    Raises `RuntimeError` if `reference` is not found in the data.
138    """
139    matrix = {
140        "type": "object",
141        "additionalProperties": {
142            "type": "object",
143            "additionalProperties": {"type": ["number", "null"]},
144        },
145    }
146
147    schema = {
148        "type": "object",
149        "required": ["league"],
150        "properties": {
151            "league": {
152                "type": "object",
153                "required": ["md", "lower", "upper"],
154                "properties": {
155                    "md": matrix,
156                    "lower": matrix,
157                    "upper": matrix,
158                    "pval": matrix,
159                },
160            }
161        },
162    }
163
164    jsonschema.validate(instance=data, schema=schema)
165    ref = re.sub(r"[^A-Za-z0-9_]", "_", reference)
166    if ref not in data["league"]["md"]:
167        raise RuntimeError("Missing reference")
168
169    label = "[95% CI]" if "pval" in data["league"] else "[95% CrI]"
170    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.
  • 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:
173def prediction_table(data: dict) -> plt.Figure:
174    """Grid of prediction intervals. Only applicable to NMA results.
175
176    Parameters:
177    - `data`: Result dict from `tombolo.nma`.
178
179    Each cell shows the 95% prediction interval for the row treatment relative to the column treatment.
180    """
181    matrix = {
182        "type": "object",
183        "additionalProperties": {
184            "type": "object",
185            "additionalProperties": {"type": ["number", "null"]},
186        },
187    }
188
189    schema = {
190        "type": "object",
191        "required": ["prediction"],
192        "properties": {
193            "prediction": {
194                "type": "object",
195                "required": ["lower", "upper"],
196                "properties": {"lower": matrix, "upper": matrix},
197            }
198        },
199    }
200
201    jsonschema.validate(instance=data, schema=schema)
202    return _grid(data["prediction"])

Grid of prediction intervals. Only applicable to NMA results.

Parameters:

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

def convergence_table(data: dict) -> matplotlib.figure.Figure:
205def convergence_table(data: dict) -> plt.Figure:
206    """Summary table of MCMC convergence diagnostics. Only applicable to BNMA results.
207
208    Parameters:
209    - `data`: Result dict from `tombolo.bnma`.
210
211    Returns R-hat (max), ESS bulk (min), and ESS tail (min) across all model parameters.
212    """
213    schema = {
214        "type": "object",
215        "required": ["convergence"],
216        "properties": {
217            "convergence": {
218                "type": "object",
219                "required": ["rhat_max", "ess_bulk_min", "ess_tail_min"],
220                "properties": {
221                    "rhat_max": {"type": "number"},
222                    "ess_bulk_min": {"type": "number"},
223                    "ess_tail_min": {"type": "number"},
224                },
225            }
226        },
227    }
228    jsonschema.validate(instance=data, schema=schema)
229    return _table(data["convergence"])

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

Parameters:

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