diff --git a/README.md b/README.md index addbf32..c1a29c2 100644 --- a/README.md +++ b/README.md @@ -52,12 +52,13 @@ print(result.top_features(5)) print(result.top_interactions(3)) print(f"Ricci: {result.manifold_curvature:.4f} FIM: {result.fim_quality}") -# All 13 visualisation types — dark and light themes +# All 14 visualisation types — dark and light themes result.plot("gsf_bar", theme="dark") result.plot("force", theme="dark") result.plot("waterfall", theme="dark") result.plot("heatmap", theme="dark") result.plot("beeswarm", theme="dark", batch_results=batch) +result.plot("dependence", theme="dark", batch_results=batch) result.plot("network", theme="dark") result.plot("curvature", theme="dark") result.plot("attention_heatmap", theme="dark") @@ -70,7 +71,7 @@ result.plot("triplet_hypergraph", theme="dark") # interaction_order=3 --- -## All 13 visualisations — what they show and how to read them +## All 14 visualisations — what they show and how to read them ### 1 · GSF Attribution Bar Chart (`gsf_bar`) @@ -181,7 +182,25 @@ instances — the GEMEX equivalent of SHAP's beeswarm summary plot. --- -### 6 · Feature Interaction Network (`network`) +### 6 · Geodesic Dependence Plot (`dependence`) + +**What it shows:** A dependence view for the two most influential features in +the current explanation. Each panel plots the original feature value against its +GSF attribution across a batch of instances, with colour indicating the strongest +holonomy interaction partner for that feature. + +**How to read it:** +- **X-axis** → original feature value. +- **Y-axis** → signed GSF attribution for that feature. +- **Gold diamond** → the currently explained instance. +- **Trend line** → how attribution changes as the feature value varies across the + reference batch. +- **Point colour** → the interacting feature with the strongest PTI relationship. +- Requires `batch_results=batch` for a meaningful population-level view. + +--- + +### 7 · Feature Interaction Network (`network`)
GEMEX interaction network @@ -205,7 +224,7 @@ statistical manifold. --- -### 7 · Geodesic Arc-Length Profile (`curvature`) +### 8 · Geodesic Arc-Length Profile (`curvature`)
GEMEX geodesic arc-length profile @@ -233,7 +252,7 @@ the surface bends at each step along the path. --- -### 8 · Feature Attention Heatmap (`attention_heatmap`) +### 9 · Feature Attention Heatmap (`attention_heatmap`)
GEMEX FAS attention heatmap @@ -260,7 +279,7 @@ captures this temporal dimension of explanation. --- -### 9 · Attention Dwell Bar Chart (`attention_dwell`) +### 10 · Attention Dwell Bar Chart (`attention_dwell`)
GEMEX attention dwell bar chart @@ -286,7 +305,7 @@ concentrated during the explanation journey. --- -### 10 · Attention vs Effect Scatter (`attention_vs_effect`) +### 11 · Attention vs Effect Scatter (`attention_vs_effect`)
GEMEX attention vs effect scatter @@ -312,7 +331,7 @@ four quadrants each have a distinct interpretation, labelled directly on the plo --- -### 11 · Bias Trap Detection (`bias`) +### 12 · Bias Trap Detection (`bias`)
GEMEX bias trap detection @@ -339,7 +358,7 @@ or GradCAM. Each bar is a stacked score from three independent geometric indicat --- -### 12 · GeodesicCAM / ManifoldSeg / PerturbFlow (`image_trio`) +### 13 · GeodesicCAM / ManifoldSeg / PerturbFlow (`image_trio`) **What it shows:** Three-panel image explanation for `data_type='image'`: - **Panel 1 (Original)** — the input image. @@ -367,7 +386,7 @@ identifies the left upper lobe as the dominant region using only `predict_proba( --- -### 13 · Triplet Hypergraph (`triplet_hypergraph`) +### 14 · Triplet Hypergraph (`triplet_hypergraph`) Requires `interaction_order=3` in `GemexConfig`. @@ -592,10 +611,10 @@ pip install gemex[full] # all backends | 08 | `08_dermamnist.py` | Image | DermaMNIST — Skin lesions HAM10000 (7 classes) | | 09 | `09_organamnist.py` | Image | OrganAMNIST — Abdominal CT organs (11 classes) | | 10 | `10_bloodmnist.py` | Image | BloodMNIST — Blood cell microscopy (8 classes, RGB) | -| 11 | `11_gemex_tabular_plots.py` | Tabular | Heart Disease — waterfall, heatmap, curvature plots | +| 11 | `11_alternative_plots_tabular.py` | Tabular | Heart Disease — waterfall, heatmap, curvature plots | | 12 | `12_triplet_hypergraph.py` | Tabular | Heart Disease — RCT three-way interactions hypergraph | | 13 | `13_image_trio.py` | Image | PneumoniaMNIST / OrganAMNIST / BloodMNIST — standalone image_trio | -| 14 | `14_all_plots_showcase.py` | Tabular | Pima Diabetes — all 13 plot types in one run | +| 14 | `14_all_plots_showcase.py` | Tabular | Pima Diabetes — all applicable tabular plot types in one run | --- diff --git a/examples/11_alternative_plots_tabular.py b/examples/11_alternative_plots_tabular.py index 408d6f1..0a76b12 100644 --- a/examples/11_alternative_plots_tabular.py +++ b/examples/11_alternative_plots_tabular.py @@ -6,8 +6,8 @@ # # GEMEX: Geodesic Entropic Manifold Explainability v1.2.2 """ -11_gemex_tabular_plots.py -======================= +11_alternative_plots_tabular.py +=============================== Demonstrates three plot types added in v1.2.2 on tabular medical data: waterfall — cumulative GSF attribution from baseline to prediction @@ -22,9 +22,9 @@ Usage ----- - python 11_gemex_tabular_plots.py - python 11_gemex_tabular_plots.py --heart-path ./cleveland_heart.csv - python 11_gemex_tabular_plots.py --theme light --save-dir ./gemex_tabular_plots + python 11_alternative_plots_tabular.py + python 11_alternative_plots_tabular.py --heart-path ./cleveland_heart.csv + python 11_alternative_plots_tabular.py --theme light --save-dir ./gemex_tabular_plots """ import argparse diff --git a/examples/14_all_plots_showcase.py b/examples/14_all_plots_showcase.py index 074584e..a8e99d9 100644 --- a/examples/14_all_plots_showcase.py +++ b/examples/14_all_plots_showcase.py @@ -8,15 +8,17 @@ """ 14_all_plots_showcase.py ============================ -One-stop showcase of every plot type available in GEMEX v1.2.2. +One-stop showcase of the tabular plot types available in GEMEX v1.2.2. Dataset: Pima Indians Diabetes (UCI, 8 features) -Produces one output PNG per plot kind for a positive (Diabetes) instance: +Produces one output PNG per applicable tabular plot kind for a positive +(Diabetes) instance: gsf_bar — feature attribution bar with uncertainty force — force/push-pull diagram waterfall — cumulative attribution from baseline to prediction heatmap — feature × instance GSF grid (20-instance batch) + dependence — feature dependence against GSF attribution curvature — geodesic arc-length profile triplet_hypergraph — three-way RCT interactions as hypergraph network — holonomy interaction network (PTI) @@ -25,9 +27,9 @@ attention_vs_effect — attention vs attribution scatter bias — bias trap detection (BTD) beeswarm — batch GSF distribution - image_trio — not applicable to tabular data + image_trio — image-only; see 13_image_trio.py -interaction_order=3 is used so that all plot types including +interaction_order=3 is used so that all tabular plot types including triplet_hypergraph are available. Requirements @@ -160,6 +162,7 @@ def main(): ('force', {}, 'Force / push-pull diagram'), ('waterfall', {}, 'Cumulative waterfall'), ('heatmap', {'batch_results': batch}, 'Feature x instance heatmap'), + ('dependence', {'batch_results': batch}, 'Geodesic dependence plot'), ('curvature', {}, 'Geodesic arc-length profile'), ('triplet_hypergraph', {'top_n': 10}, 'RCT triplet hypergraph'), ('network', {}, 'Holonomy interaction network'), diff --git a/gemex/viz/plots.py b/gemex/viz/plots.py index 8e478b1..f0799e9 100644 --- a/gemex/viz/plots.py +++ b/gemex/viz/plots.py @@ -81,8 +81,6 @@ def plot(self, kind: str = "gsf_bar", theme: str = "dark", **kwargs): raise NotImplementedError(f"Plot '{kind}' not yet implemented.") return fn(t, **kwargs) - # ── individual plot methods (delegated to standalone functions) ── # - def _plot_gsf_bar(self, t, **kw): return _gsf_bar(self.r, t, **kw) @@ -137,7 +135,6 @@ def _gsf_bar(r, t, figsize=(8, 5.5), save_path=None, **kw): curv = abs(r.manifold_curvature) order = np.argsort(np.abs(gsf))[::-1] gsf_s = gsf[order]; nm_s = [names[i] for i in order] - # Fix 4: use real curvature-weighted per-feature uncertainty raw_unc = getattr(r, 'gsf_uncertainty', np.abs(gsf) * curv * 0.22) unc = raw_unc[order] max_g = np.max(np.abs(gsf_s)) + 1e-10 @@ -244,9 +241,6 @@ def _force(r, t, figsize=(9, 6), save_path=None, **kw): return fig -# Remaining plot functions are thin wrappers that call the standalone scripts -# from the final scripts already developed. For brevity they delegate to helpers. - def _beeswarm(r, t, batch_results=None, figsize=(9,5.8), save_path=None, **kw): import matplotlib.pyplot as plt, matplotlib.lines as ml import matplotlib.colors as mc, numpy as np @@ -320,11 +314,6 @@ def _beeswarm(r, t, batch_results=None, figsize=(9,5.8), save_path=None, **kw): return fig -# Remaining plots (dependence, attention_*, bias, network, image_trio) -# delegate to the standalone scripts in the examples/ folder. -# They are called identically but return a matplotlib Figure. - - # ══════════════════════════════════════════════════════════════════════ # P4 — Geodesic Dependence Plot # ══════════════════════════════════════════════════════════════════════ @@ -1618,7 +1607,6 @@ def _timeseries_attribution(r, t, # ═══════════════════════════════════════════════════════════════ # Panel 3 — Per-step GSF attribution bars # ═══════════════════════════════════════════════════════════════ - # Fix 4: use real per-feature uncertainty if available raw_unc = getattr(r, 'gsf_uncertainty', np.abs(gsf) * curv * 0.22) unc = raw_unc cols_b = [t['pos'] if g > 0 else t['neg'] for g in gsf]