CPPStructurePlot.interactive

CPPStructurePlot.interactive(predictor, sequence, pdb=None, uniprot=None, col_imp='feat_impact', col_val='mean_dif', shap_plot=True, tmd_len=20, mode='impact', focus='fade', focus_region=None, size_by_impact=True, normalize_by_span=False, feature_map=True, site_to_start=None, chain=None, init_site=None, debounce_ms=250)[source]

Build a live, selection-linked explorer that re-predicts and repaints on each site.

Returns an ipywidgets panel ([pro], needs ipywidgets) reproducing the deployed app’s per-site explore loop in a notebook: a site slider drives a user predictor that returns a df_feat for that site, and both the 3D structure (the map_structure() render path) and the CPPPlot.feature_map() repaint in place from that one selection — reading the same per-residue impact. Rapid changes are debounced so the predictor is not re-run on every intermediate slider value.

The exact prediction itself runs on the live Python kernel via predictor; this class does not hard-code CPP / TreeModel / ShapModel.

A highlight (position) slider links the feature map to the structure: pick a residue in the current window and it lights up in the 3D cartoon (a bold marker) while a vertical line marks its feature-map column — without re-running the predictor. When the ipympl (%matplotlib widget) backend is active the feature map is also clickable (clicking a column drives the same highlight); ipympl is optional — the slider is the always-present link, so no extra dependency is required.

Added in version 1.1.0.

Parameters:
  • predictor (callable) – User callable (sequence, p1) -> df_feat returning a feature DataFrame (with the col_imp and feature-map columns) for the site p1. Example wiring CPP + ShapModel into such a callable is shown in the notebook.

  • sequence (str) – Full protein sequence; the site slider ranges over 1..len(sequence).

  • pdb (str, optional) – Path to a .pdb / .cif structure file. Exactly one of pdb or uniprot must be given. The structure is parsed once and reused across selections.

  • uniprot (str, optional) – UniProt accession; the AlphaFold model is fetched once into a temporary folder. Exactly one of pdb or uniprot must be given.

  • col_imp (str, default='feat_impact') – Column of the predictor’s df_feat holding the signed per-feature impact.

  • col_val (str, default='mean_dif') – Column shown in the feature-map heatmap cells.

  • shap_plot (bool, default=True) – Passed to CPPPlot.feature_map().

  • tmd_len (int, default=20) – Length of the TMD (>=1). Must match the geometry the predictor’s features use.

  • mode ({'impact', 'plddt'}, default='impact') – Initial structure colouring (a live dropdown also toggles it).

  • focus ({'whole', 'fade', 'zoom'}, default='fade') – Initial structure framing (a live dropdown also toggles it).

  • focus_region (tuple or list of tuples, optional) – Fixed (start, stop) focus window; default derives it from each selection’s df_feat positions.

  • size_by_impact (bool, default=True) – Scale each impact residue’s stick / marker by |impact| (impact mode only).

  • normalize_by_span (bool, default=False) – Per-residue aggregation for the structure colouring; see map_structure().

  • feature_map (bool, default=True) – If True, show the linked CPPPlot.feature_map() panel; if False, the 3D structure panel only.

  • site_to_start (callable, optional) – Maps the selected site to the structure anchor start (first JMD-N residue): p1 -> start. Default lambda p1: p1 - jmd_n_len (the site is the first TMD residue). Supply your own to match a different window geometry.

  • chain (str, optional) – Chain id to render; default selects the best-matching / first amino-acid chain.

  • init_site (int, optional) – Initial selected site (default the middle of sequence).

  • debounce_ms (int, default=250) – Coalesce slider/dropdown changes within this many milliseconds into one predictor call and repaint (>=0; 0 renders synchronously).

Returns:

panel – A widget container (controls + linked structure / feature-map outputs) that displays inline in Jupyter.

Return type:

ipywidgets.Widget

Raises:
  • ValueError – On invalid arguments (e.g. predictor not callable, neither or both of pdb / uniprot, an unknown mode / focus, an out-of-range init_site).

  • RuntimeError – If ipywidgets is not installed, or an AlphaFold model cannot be fetched.

Examples

A live, selection-linked explorer: a site slider drives a user predictor that returns a df_feat for that site, and both the 3D structure and the ``CPPPlot.feature_map`` repaint in place from that one selection. This is the notebook-native version of the deployed cleavage app’s per-site explore loop, driven by the real Python model on a live kernel. Rapid slider moves are debounced.

This is a pro feature (needs biopython + py3Dmol + ipywidgets). Run it in a live Jupyter kernel to drag the slider.

import pandas as pd
import aaanalysis as aa
import aaanalysis.utils as ut

aa.options["verbose"] = False

interactive is model-agnostic: pass a ``predictor(sequence, p1) -> df_feat`` callable. In a real analysis it wraps CPP.run + ShapModel/TreeModel for the window around p1:

def predictor(sequence, p1):
    df_seq = make_window_df_seq(sequence, p1)     # your windowing around the site
    df_feat = cpp.run(labels=labels, ...)         # CPP feature discovery
    sm = aa.ShapModel().fit(X, labels=labels)     # per-sample SHAP impact
    return sm.add_feat_impact(df_feat=df_feat)    # df_feat with a feat_impact column

For a self-contained, fast example we use a stub predictor returning a fixed df_feat; the linked repaint and controls behave identically.

df_cat = aa.load_scales(name='scales_cat').head(5).reset_index(drop=True)
splits = ['Segment(1,2)', 'Segment(2,2)', 'Segment(1,1)', 'Pattern(C,1)', 'Segment(1,4)']
parts = ['TMD', 'TMD', 'JMD_N', 'TMD', 'JMD_C']
df_feat = pd.DataFrame({
    ut.COL_FEATURE: [f"{parts[i]}-{splits[i]}-{r[ut.COL_SCALE_ID]}" for i, r in df_cat.iterrows()],
    'category': df_cat[ut.COL_CAT], 'subcategory': df_cat[ut.COL_SUBCAT],
    'scale_name': df_cat[ut.COL_SCALE_NAME],
    'abs_auc': [0.2, 0.15, 0.3, 0.1, 0.25], 'abs_mean_dif': [0.3, 0.2, 0.5, 0.4, 0.35],
    'mean_dif': [0.3, -0.2, 0.5, -0.4, 0.25], 'std_test': 0.1, 'std_ref': 0.1,
    'feat_impact': [0.8, -0.5, 1.2, -0.3, 0.6]})

def predictor(sequence, p1):
    # A real predictor re-runs CPP/SHAP for the window at p1; here we return a fixed df_feat.
    return df_feat

# Human lysozyme C (P61626): the AlphaFold structure and its sequence (the slider ranges over it).
sequence = 'MKALIVLGLVLLSVTVQGKVFERCELARTLKRLGMDGYRGISLANWMCLAKWESGYNTRATNYNAGDRSTDYGIFQINSRYWCNDGKTPGAVNACHLSCSALLQDNIADAVACAKRVVRDPQGIRAWVAWRNRCQNRDVRQYVQGCGV'

Drag the site (P1) slider to re-predict and repaint both views; the colour (impact/plddt) and focus (whole/fade/zoom) dropdowns restyle the structure. site_to_start maps the selected site to the structure anchor (default p1 - jmd_n_len); feature_map=False shows the 3D panel only; debounce_ms coalesces rapid moves.

A highlight slider links the feature map to the structure: pick a residue in the current window and it lights up in the 3D cartoon (a bold cyan marker) while a vertical line marks its feature-map column — without re-running the predictor. With the ipympl backend (%matplotlib widget) the feature map is also clickable (click a column to drive the same highlight); ipympl is optional — the slider is the always-present link.

csp = aa.CPPStructurePlot(jmd_n_len=10, jmd_c_len=10, verbose=False)
panel = csp.interactive(predictor=predictor, sequence=sequence, uniprot='P61626',
                        col_imp='feat_impact', tmd_len=10, mode='impact', focus='fade',
                        feature_map=True, init_site=40, debounce_ms=250)
panel
VBox(children=(HBox(children=(IntSlider(value=40, continuous_update=False, description='site (P1)', max=148, m…

site_to_start maps the selected P1 to the structure anchor (the first JMD-N residue; default p1 - jmd_n_len). Override it when P1 is not the first TMD residue (e.g. a cleavage P1). size_by_impact scales sticks by |impact|; normalize_by_span switches the per-residue aggregation.

csp.interactive(predictor=predictor, sequence=sequence, uniprot='P61626', col_imp='feat_impact',
                tmd_len=10, init_site=40, size_by_impact=True, normalize_by_span=False,
                site_to_start=lambda p1: p1 - 8)   # custom anchor mapping
VBox(children=(HBox(children=(IntSlider(value=40, continuous_update=False, description='site (P1)', max=148, m…

For a one-shot static side-by-side instead of the live explorer, use CPPStructurePlot.plot_combined; for the 3D structure alone, CPPStructurePlot.map_structure.