plots¶
Plotting utilities to surface metric-to-metric relationships.
These plots make the sample-vs-alarm gap (Andrade 2024), threshold sensitivity, cadence sensitivity, and IoC vs surrogate transparent. All return (fig, ax); none save to disk — that’s the caller’s job.
- scitex_seizure_metrics.plots.cadence_ablation(sweep_df, *, ax=None, x='cadence_s', y='fp_per_hour', logx=True)[source]¶
How does FP/hr (or any metric) move as we change the cadence? Input: forecasting.sweep_policies output sorted by cadence.
- scitex_seizure_metrics.plots.ioc_vs_surrogate(sweep_df, *, ax=None)[source]¶
IoC (sensitivity − surrogate_sensitivity) across thresholds. Useful to see the threshold range where the model truly beats chance.
- scitex_seizure_metrics.plots.metric_correlation_heatmap(per_patient_df, *, ax=None, metrics=None, method='spearman')[source]¶
Heatmap of metric-to-metric correlations across patients. Surfaces redundancy (“this metric tells us nothing new”) and the sample-vs-alarm divergence axis.
- Parameters:
method (str)
- scitex_seizure_metrics.plots.reliability_diagram(cal_report, *, ax=None, title='Reliability diagram')[source]¶
Plot a reliability diagram from a CalibrationReport.
The dashed identity line represents perfect calibration. Bin counts are shown via marker size.
- Parameters:
title (str)
- scitex_seizure_metrics.plots.sample_vs_alarm_scatter(per_patient_df, *, ax=None, x_metric='roc_auc', y_metric='sensitivity')[source]¶
Reproduce the Andrade 2024 finding: per-patient sample-based AUC vs alarm-based sensitivity. Identity line shows the (false) hope of direct correspondence.
- scitex_seizure_metrics.plots.sensitivity_tiw(curves, *, ax=None, percent=True, show_chance=True, mark_operating_point=True, labels=None, aspect=1.0, save_path=None)[source]¶
Sensitivity vs time-in-warning trade-off (Karoly 2017 Fig 6).
The field-standard forecasting view: each subject’s empirical operating curve plotted as sensitivity (y) against time-in-warning (x), overlaid on the chance diagonal (sensitivity == TiW). A curve above the diagonal carries signal beyond a time-matched coin.
The drawn curve is each subject’s monotone upper envelope — the best sensitivity achievable at each time-in-warning budget (a forecaster can always discard signal to slide down-left, so the envelope is the meaningful operating frontier). Drawing the envelope guarantees the target-budget operating-point marker sits on the curve rather than floating above or below a linearly-interpolated raw polyline.
- Parameters:
curves – a single
SensitivityTiWCurveor an iterable of them (one line per subject).ax – existing axis to draw on; a new figure is made if None.
percent (bool) – show axes as percentages (0-100) instead of fractions.
show_chance (bool) – overlay the chance diagonal.
mark_operating_point (bool) – mark each curve’s sensitivity-at-target-TiW operating point (lands on the envelope).
labels – optional list of legend labels (one per curve); falls back to each curve’s
.name(capital-first).aspect (float) – data aspect ratio (height / width). Defaults to
1.0so the square 0-100 % axes are visually square; pass"auto"to let matplotlib stretch to the axes box.save_path (str | None) – if given, save the figure as both .png and .pdf (the extension of
save_pathis ignored).
- Returns:
(fig, ax). Following package convention, nothing is written to disk unless
save_pathis supplied.
References
Karoly PJ et al., Brain 2017; 140: 2169 (Fig 6). Karoly 2019.
- scitex_seizure_metrics.plots.sensitivity_vs_fp_per_hour(sweep_df, *, ax=None, acceptable_fp_per_hour=0.15, wearable_fp_per_hour=0.042)[source]¶
Operating-curve plot from forecasting.sweep_thresholds output.
Plots sensitivity (y) vs FP/hr (x). Optional reference lines for Mormann’s 0.15/h and the wearable target 0.042/h.