nichesphere.sankey_plot.plot_custom_sankey

nichesphere.sankey_plot.plot_custom_sankey#

nichesphere.sankey_plot.plot_custom_sankey(adata, table_key='TPO_x_EV', filter_df=None, source_cell=None, ligand_gene=None, receptor_gene=None, target_cell=None, ligand_list=None, receptor_list=None, threshold=25, title='Parallel Flow Map', save_path=None)#

Flat 2D Sankey diagram of ligand-receptor interactions from pyCrossTalkeR results.

Visualises the flow of differential LR communication scores across four hierarchical layers — source cell type → ligand → receptor → target cell type — as a flat, R-style Sankey diagram built with Plotly. Links are drawn with uniform widths so that the diagram emphasises which interactions are active rather than their relative magnitudes; actual LRScore values are encoded by link colour (positive scores in soft red, negative in soft blue) and exposed on hover, with a diverging colour bar for reference.

All optional filters are combined with strict AND logic: only interactions that simultaneously satisfy every supplied criterion are shown. Interactions are ranked by absolute LRScore and capped at threshold before plotting.

Parameters:
  • adata (AnnData) – AnnData object containing pyCrossTalkeR output in adata.uns['pycrosstalker']['results']['tables'].

  • table_key (str, default 'TPO_x_EV') – Key of the comparison table to retrieve from the pyCrossTalkeR results, typically in the format 'conditionA_x_conditionB'. The colour bar title is derived automatically from this key (e.g. 'TPO_x_EV' → 'LRScore (TPO vs EV)').

  • filter_df (pd.DataFrame or None, default None) – Optional pre-computed filter table with a boolean 'filter' column (1 = keep). Its index must match 'source->target' strings. Only interactions whose source->target key appears in filter_df with filter == 1 are retained before any other filtering step is applied.

  • source_cell (str or list of str or None, default None) – Source cell type(s) to include. Accepts a single string or a list; if None, all source cell types are kept.

  • ligand_gene (str or None, default None) – Substring filter applied to gene_A (case-insensitive). Useful for quickly finding a specific ligand by partial name.

  • receptor_gene (str or None, default None) – Substring filter applied to gene_B (case-insensitive). Useful for quickly finding a specific receptor by partial name.

  • target_cell (str or list of str or None, default None) – Target cell type(s) to include. Accepts a single string or a list; if None, all target cell types are kept.

  • ligand_list (list of str or None, default None) – Exact-match whitelist of ligand gene names (e.g. a biological process gene set such as ECM glycoproteins). The |L suffix produced by pyCrossTalkeR is stripped before matching, and comparison is case-insensitive. Takes precedence over ligand_gene when both are provided (both filters are applied).

  • receptor_list (list of str or None, default None) – Exact-match whitelist of receptor gene names. The |R suffix is stripped before matching; comparison is case-insensitive.

  • threshold (int, default 25) – Maximum number of interactions to display. After all filters are applied, interactions are sorted by absolute LRScore (descending) and only the top threshold are plotted.

  • title (str, default 'Parallel Flow Map') – Title displayed above the Sankey diagram and used as the default filename stem when saving.

  • save_path (str or None, default None) – If provided, the figure is saved as a self-contained HTML file (the extension is replaced with .html regardless of what is passed). The HTML embeds a Plotly toolbar configured to export SVG, and a JavaScript snippet that automatically triggers the download button one second after the page loads. The file is then opened in the default web browser. Check the browser’s downloads directory for the resulting .svg file.

Returns:

fig – The Plotly figure object, which can be displayed with fig.show() or further customised before rendering. Returns None if no interactions match the specified filters.

Return type:

plotly.graph_objects.Figure or None

Raises:

KeyError – If adata.uns does not contain a 'pycrosstalker' key.

Notes

  • Link widths are deliberately uniform (all set to 1) so the layout emphasises the topology of active interactions rather than their magnitude. The actual LRScore is available on hover and via the colour bar.

  • The four-layer node structure appends role suffixes ((Src), (Lig), (Rec), (Tgt)) internally to disambiguate nodes that share a name across layers (e.g. a gene that appears as both ligand and receptor); these suffixes are stripped from the visible node labels in the final plot.

  • Saving relies on the browser’s built-in download mechanism rather than kaleido or orca, making it dependency-free for vector export.

Examples

Basic usage — plot all interactions from a comparison table:

>>> fig = nichesphere.comm.plot_custom_sankey(adata, table_key='TPO_x_EV')
>>> fig.show()

Filter to a specific source cell type and a gene-set list:

>>> ecm_genes = ['FN1', 'COL1A1', 'THBS1', 'VTN']
>>> fig = nichesphere.comm.plot_custom_sankey(
...     adata,
...     table_key='TPO_x_EV',
...     source_cell='Fibroblast',
...     ligand_list=ecm_genes,
...     threshold=20,
...     title='ECM Glycoprotein Signalling – TPO vs EV',
...     save_path='figures/ecm_sankey.html',
... )