sceleto.interaction¶
Cell–cell communication inference — a Python port of CellChat. Infers
ligand–receptor–mediated signaling between cell groups in an
AnnData, using the curated CellChatDB database.
Database¶
- sceleto.interaction.load_cellcommdb(species: str = 'human') CellCommDB[source]¶
Load the bundled CellChatDB for a species.
Parameters¶
- species
One of
"human","mouse","zebrafish".
Returns¶
- CellCommDB
Loaded database with interaction / complex / cofactor / geneinfo tables.
- sceleto.interaction.load_ppi(species: str = 'human') DataFrame[source]¶
Load the bundled protein–protein interaction edge list.
Ships the CellChat PPI network for the (not-yet-ported) expression-smoothing / diffusion step (
smoothData/projectDatain R). Provided so the data is available; the smoothing step itself is not implemented yet, so the current pipeline does not consume this. Only"human"and"mouse"are available.Returns¶
- pd.DataFrame
Columns
gene_i,gene_j,weight(undirected edges).
- sceleto.interaction.list_cellcommdb() list[str][source]¶
Return the species for which a CellChatDB is bundled.
- class sceleto.interaction.CellCommDB(species: str, interaction: DataFrame, complex: DataFrame, cofactor: DataFrame, geneinfo: DataFrame)[source]¶
Bases:
objectA loaded CellChatDB for one species.
Attributes¶
- species
One of
"human","mouse","zebrafish".- interaction
Ligand–receptor interaction table (indexed by
name).- complex
Complex → subunit table (indexed by complex name).
- cofactor
Cofactor sets (indexed by cofactor name).
- geneinfo
Single-column frame of official gene symbols.
- interaction: DataFrame¶
- complex: DataFrame¶
- cofactor: DataFrame¶
- geneinfo: DataFrame¶
- resolve_genes(name: str) list[str][source]¶
Resolve a ligand/receptor token to its constituent gene symbols.
A single gene resolves to
[name]; a complex resolves to its non-empty subunits (order preserved). Unknown tokens resolve to[name](treated as a single gene).Parameters¶
- name
A gene symbol or a complex name from the
ligand/receptorcolumns ofinteraction.
- resolve_cofactor(name: str) list[str][source]¶
Resolve a cofactor-set name to its gene symbols (
[]if blank).
- subset(*, annotation: str | Sequence[str] | None = None, pathway: str | Sequence[str] | None = None) CellCommDB[source]¶
Return a new
CellCommDBwith the interaction table filtered.Parameters¶
- annotation
Keep only interactions with these annotation class(es). See
ANNOTATIONS.- pathway
Keep only interactions in these signaling pathway(s).
Gene-symbol Normalization¶
- class sceleto.interaction.GeneMapper(symbols: Iterable[str], synonyms: dict[str, list[str]] | None = None, *, case_insensitive: bool = True)[source]¶
Bases:
objectMap query gene symbols onto a reference symbol set, alias-aware.
Parameters¶
- symbols
Canonical reference symbols (the database’s official symbols).
- synonyms
Optional
{canonical_symbol: [alias, ...]}. Aliases are matched only when they are unambiguous — an alias pointing at more than one canonical symbol is dropped from the alias table (a conservative choice: better to leave it unmatched than to guess wrong).- case_insensitive
Also match on a case-folded key. Enables e.g. human
TGFB1in the DB to catch a query writtenTgfb1, which matters when a mouse-cased object is scored against the human DB or vice versa. Direct (case-sensitive) hits always take priority over case-folded ones.
- classmethod from_db(db, *, case_insensitive: bool = True) GeneMapper[source]¶
Build a
GeneMapperfrom a loadedCellCommDB.Uses
db.geneinfo(Symbol+ space-separatedSynonym).
- resolve(symbol: str) str | None[source]¶
Resolve one query symbol to a canonical symbol, or
None.Resolution order: exact canonical → exact alias → case-folded canonical → case-folded alias.
- map(query: Iterable[str]) MappingResult[source]¶
Map a set of query symbols onto canonical symbols.
Parameters¶
- query
Query gene symbols (e.g.
adata.var_names).
Returns¶
- MappingResult
Full breakdown of direct / alias / unmatched resolutions.
- rename_frame(adata_var_names: Iterable[str]) dict[str, str][source]¶
Return a collision-safe rename dict → canonical symbols.
Only entries that actually change are returned, suitable for
adata.var.rename(index=...). Direct matches are omitted (no change).Renames that would collide are dropped so the result never introduces duplicate var_names: an alias is not renamed to a canonical that is already present among the query names, nor to a canonical that two different aliases both target. This prevents silently overwriting a real gene’s expression column (e.g. a panel carrying both
TGFB1and a legacy alias of it).
- class sceleto.interaction.MappingResult(mapping: dict[str, str], matched_direct: set[str], matched_alias: dict[str, str], unmatched: set[str])[source]¶
Bases:
objectOutcome of mapping a query gene set onto canonical symbols.
Attributes¶
- mapping
{query_symbol: canonical_symbol}for every query that resolved.- matched_direct
Queries that matched a canonical symbol as-is.
- matched_alias
{query_symbol: canonical_symbol}resolved through a synonym.- unmatched
Queries that matched nothing.
Core Inference¶
The CellComm class drives the whole pipeline;
its methods mirror CellChat’s workflow: identify_overexpressed →
compute_communication → filter_communication →
compute_communication_pathway → aggregate → subset_communication /
rank_net / contribution.
- class sceleto.interaction.CellComm(adata: AnnData, groupby: str, *, db: CellCommDB | None = None, species: str = 'human', layer: str | None = None, map_symbols: bool = True, coordinates: ndarray | None = None, spatial_factors: dict | None = None, verbose: bool = True)[source]¶
Bases:
objectCell–cell communication analysis over an
AnnData.Parameters¶
- adata
Cells × genes AnnData with normalized, non-negative expression in the chosen layer (log-normalized
.Xis typical).- groupby
adata.obscolumn with the cell-group labels. Its categorical order (or sorted uniques) defines the network’s node order.- db
A loaded
CellCommDB. IfNone, loads the species default.- species
Used only when
db is Noneto pick the bundled database.- layer
Layer to read expression from;
Noneusesadata.X.- map_symbols
If
True(default), normalizeadata.var_namesonto database canonical symbols (alias/case-aware) before analysis — this is what makes cross-species and symbol-update mismatches recoverable.- verbose
Print progress.
Notes¶
The AnnData is not copied;
compute_communicationwrites results intoself(and, optionally,adata.uns['cellcomm']viato_uns()).- property is_computed: bool¶
Whether
compute_communication()has run.
- property prob: ndarray¶
Per-pair communication probability (K×K×nLR).
- property pval: ndarray¶
Per-pair permutation p-values (K×K×nLR).
- property weight: ndarray¶
Aggregated K×K interaction-strength matrix (needs aggregate()).
- property count: ndarray¶
Aggregated K×K interaction-count matrix (needs aggregate()).
- identify_overexpressed(*, thresh_p: float = 0.05, thresh_fc: float = 0.0, thresh_pc: float = 0.0, only_pos: bool = True, variable_both: bool = True) CellComm[source]¶
DE (Wilcoxon, one-vs-rest via scanpy) → significant L–R pairs.
Populates
overexpressed_,features_sig_, andLRsig(the exact pair setcompute_communication()scores).Parameters¶
- thresh_p
Adjusted-p cutoff for a gene to count as over-expressed.
- thresh_fc
Minimum log-fold-change.
- thresh_pc
Minimum detection fraction in the group.
- only_pos
Keep only up-regulated genes.
- variable_both
If
True, keep an interaction only when both ligand and receptor are over-expressed; else either endpoint suffices (mirrors CellChatvariable.both).
- compute_communication(*, type: str = 'triMean', trim: float = 0.1, population_size: bool = False, nboot: int = 100, seed: int = 1, Kh: float = 0.5, n: float = 1.0, n_jobs: int = 1, distance_use: bool = True, interaction_range: float = 250.0, scale_distance: float = 0.01, k_min: int = 10, contact_dependent: bool = True, contact_range: float | None = None) CellComm[source]¶
Communication probability + permutation p-value per L–R pair.
Requires
identify_overexpressed()first (or a manually setLRsig). Writesself.net = {'prob', 'pval'}: each aK × K × nLRarray (sender × receiver × interaction).Parameters¶
- type, trim
Group-summary statistic (
triMeandefault) and trim fraction.- population_size
Weight probabilities by group cell-fractions (CellChat
population.size).- nboot
Number of label permutations for the p-value.
- seed
RNG seed for the permutations.
- Kh, n
Hill function parameters (dissociation constant, coefficient).
- n_jobs
Threads for the permutation bootstrap (the dominant cost).
1(default) runs serially; higher values parallelize the per-boot group averaging. Results are identical regardless ofn_jobs.- distance_use, interaction_range, scale_distance, k_min, contact_dependent, contact_range
Spatial only (when the object was built with
coordinates). Constrain communication by spatial proximity:interaction_range(µm diffusion cutoff),scale_distance(distance scaling),contact_range(µm, required ifcontact_dependentfor theCell-Cell ContactL-R pairs). Seecompute_region_distance().
- compute_communication_pathway(*, thresh: float = 0.05) CellComm[source]¶
Sum significant per-pair prob within each signaling pathway.
Writes
self.netP = {'prob' (K×K×nPathway), 'pathways' (list)}.
- filter_communication(*, min_cells: int = 10) CellComm[source]¶
Zero out communication involving cell groups with too few cells.
Ports CellChat
filterCommunication(min-cells branch): any cell group with<= min_cellscells is unreliable, so all communication where it is the sender OR receiver is set to 0. Should be called aftercompute_communication()and beforeaggregate()/compute_communication_pathway().Parameters¶
- min_cells
Cell groups with at most this many cells are excluded.
- aggregate(*, thresh: float = 0.05) CellComm[source]¶
Aggregate to K×K
countandweightmatrices.count= number of significant L–R pairs between each group pair;weight= summed communication probability.
- subset_communication(*, thresh: float = 0.05, sources: Sequence[str] | None = None, targets: Sequence[str] | None = None, signaling: Sequence[str] | None = None) DataFrame[source]¶
Tidy long-form significant communication table.
Returns¶
- pd.DataFrame
Columns:
source,target,ligand,receptor,interaction_name,pathway_name,prob,pval.
- rank_net(*, measure: str = 'weight', thresh: float = 0.05) DataFrame[source]¶
Rank signaling pathways by total information flow (
rankNet).For each pathway, “information flow” = the summed communication probability (
measure="weight") or the number of significant links (measure="count") over all group pairs. Pathways are returned in descending order.Parameters¶
- measure
"weight"(summed probability, the CellChat “information flow”) or"count"(number of significant group-pair links).- thresh
p-value threshold for significance.
Returns¶
- pd.DataFrame
Columns
pathway_name,flow(the ranking value), sorted descending.
- contribution(signaling: str, *, thresh: float = 0.05) DataFrame[source]¶
Per-L–R-pair contribution to one signaling pathway (
netAnalysis_contribution).Within a pathway, each ligand–receptor pair contributes a share of the total communication probability. Returns each pair’s summed probability and its fractional contribution, descending.
Parameters¶
- signaling
Pathway name (see
CellComm.netP["pathways"]ordb.pathways).- thresh
p-value threshold for significance.
Returns¶
- pd.DataFrame
Columns
interaction_name,ligand,receptor,prob,contribution(fraction of the pathway total), sorted descending.
- signaling_role_pathway(*, pattern: str = 'outgoing') DataFrame[source]¶
Per-pathway × cell-group signaling-role matrix (see
signaling_role_pathway()).
- compute_net_similarity(*, slot: str = 'netP', type: str = 'functional', k=None, thresh=None) CellComm[source]¶
Pairwise pathway-network similarity →
netP['similarity'][type].Delegates to
compute_net_similarity()(which returns the matrix); the method stores it and returnsselfso the manifold sub-pipeline chains:cc.compute_net_similarity().net_embedding().
- net_embedding(*, type: str = 'functional', n_neighbors=None, min_dist: float = 0.3, metric: str = 'correlation', seed: int = 42, pathway_remove=None, **umap_kwargs) CellComm[source]¶
2-D UMAP of the pathway similarity →
netP['embedding'][type].Delegates to
net_embedding(); stores the embedding and returnsself(chainable).
- net_clustering(*, type: str = 'functional', k=None, method: str = 'kmeans', k_eigen=None, n_init: int = 10, seed: int = 0) Series[source]¶
Cluster pathways in the similarity manifold (see
net_clustering()).
- identify_communication_patterns(pattern: str = 'outgoing', k=None, *, seed: int = 0, max_iter: int = 500, store: bool = True, verbose: bool = True) dict[source]¶
NMF outgoing/incoming communication patterns (see
identify_communication_patterns()).
Network Analysis¶
- sceleto.interaction.compute_centrality(mat: ndarray, names: list[str]) DataFrame[source]¶
Per-node centrality scores for one signaling network.
Parameters¶
- mat
K × Kweighted communication matrix (source × target).- names
Node (cell-group) names.
Returns¶
- pd.DataFrame
Index =
names; columns =outdeg(Sender),indeg(Receiver),flowbet(Mediator),info(Influencer), plushub,authority,eigen,pagerank.
- sceleto.interaction.signaling_role(centrality: DataFrame) DataFrame[source]¶
Assign the dominant signaling role per cell group.
For each node, reports the four core scores (Sender/Receiver/Mediator/ Influencer) and the
rolewith the highest score.
- sceleto.interaction.signaling_role_pathway(cc, *, pattern: str = 'outgoing') DataFrame[source]¶
Per-pathway × cell-group signaling-role matrix (
netAnalysis_signalingRole_heatmap).For each pathway network, computes the chosen centrality role per cell group and stacks them into a
pathway × cell-groupmatrix — the data behind the standard CellChat signaling-role heatmap.Parameters¶
- cc
A
CellCommaftercompute_communication_pathway().- pattern
Which role to score:
"outgoing"/"sender"(out-degree),"incoming"/"receiver"(in-degree),"mediator"(betweenness), or"influencer"(information centrality).
Returns¶
- pd.DataFrame
Rows = pathways, columns = cell groups, values = the role score.
Communication Patterns (NMF)¶
Outgoing/incoming communication-pattern discovery via non-negative matrix
factorization (CellChat selectK / identifyCommunicationPatterns). The
factorization uses the same Lee multiplicative-update rule as R’s NMF package
(scikit-learn NMF(solver='mu')).
- sceleto.interaction.select_k(cc: CellChat, pattern: str = 'outgoing', k_range=range(2, 11), *, n_runs: int = 30, seed: int = 10, max_iter: int = 500, verbose: bool = True) pd.DataFrame[source]¶
Rank selection for NMF communication patterns (CellChat
selectK).For each candidate
kthis runs NMFn_runstimes (varying the seed), forms the consensus clustering of cell groups over the runs, and reports two stability metrics — the same ones CellChat’sselectKreads out ofNMF::nmfEstimateRank:cophenetic : cophenetic correlation of the consensus matrix. Drops sharply at the
kbeyond which the factorization is no longer stable.silhouette : mean silhouette of the consensus clustering.
Pick the
kjust before cophenetic correlation begins to fall (a common NMF heuristic).Parameters¶
- cc
CellCommobject afterCellComm.compute_communication_pathway().- pattern
"outgoing"or"incoming".- k_range
Iterable of candidate ranks (default
range(2, 11)→ 2..10). Values abovemin(n_groups, n_pathways)are skipped with a warning.- n_runs
NMF restarts per
k(CellChat default 30). Use a smaller value for a quick scan.- seed
Base seed; run
rusesseed + rfor reproducibility.- max_iter
Maximum NMF iterations.
- verbose
Print progress.
Returns¶
- pd.DataFrame
Columns
k,cophenetic,silhouette(one row per usablek), sorted byk. Feed the chosenktoidentify_communication_patterns().
Raises¶
- ValueError
If
cc.netP['prob']is missing, the matrix is all zeros, or nokink_rangeis usable (all exceed the factorizable rank).
- sceleto.interaction.identify_communication_patterns(cc: CellComm, pattern: str = 'outgoing', k: int | None = None, *, seed: int = 0, max_iter: int = 500, store: bool = True, verbose: bool = True) dict[source]¶
NMF communication patterns (CellChat
identifyCommunicationPatterns).Factorizes the cell-group × pathway matrix into
klatent patterns. Each pattern links a group of cells (rows ofW) to a group of pathways (rows ofH), exposing coordinatedoutgoing(sending) orincoming(receiving) signaling programs.Parameters¶
- cc
A
CellCommobject afterCellComm.compute_communication_pathway()(socc.netP['prob']exists).- pattern
"outgoing"sums over the receiver axis (who sends);"incoming"sums over the sender axis (who receives).- k
Number of patterns (NMF rank). Run
select_k()first to choose it. Must satisfy1 <= k <= min(n_groups, n_pathways).- seed
Random seed passed to NMF for reproducibility.
- max_iter
Maximum NMF iterations.
- store
If
True(default), store the result oncc.patterns[pattern].- verbose
Print progress.
Returns¶
- dict
{"pattern", "k", "data", "W", "H", "cell", "signaling", "cell_pattern"}whereW: DataFrame, index = cell groups, columns =Pattern 1..k; each row is row-normalized (a cell group’s pattern memberships sum to 1), matching CellChatscaleMat(W, 'r1').H: DataFrame, index =Pattern 1..k, columns = pathways; each column is column-normalized (a pathway’s pattern memberships sum to 1), matching CellChatscaleMat(H, 'c1').cell/signaling: tidy long-form ofW/H(the Rres.pattern$cell/res.pattern$signalingtables).cell_pattern: Series mapping each cell group to its dominant pattern (argmaxoverW).data: the input cell-group × pathway matrix (pre-NMF).
Raises¶
- ValueError
If
cc.netP['prob']is missing, the matrix is all zeros, orkis out of range (kmissing,k < 1, orklarger than the number of usable groups/pathways).
- sceleto.interaction.plot_communication_patterns(cc: CellChat, pattern: str = 'outgoing', *, result: dict | None = None, figsize: tuple[float, float] = (10, 6), cmap: str = 'Spectral_r', title: str | None = None) plt.Figure[source]¶
Two-panel heatmap of the communication patterns (CellChat river view).
Left panel:
W(cell groups × patterns) — which cells drive each pattern. Right panel:Hᵀ(pathways × patterns) — which pathways define each pattern. Together they read like CellChat’sidentifyCommunicationPatternsheatmap pair.Parameters¶
- cc
CellCommobject. Usescc.patterns[pattern]unless aresultdict is passed directly.- pattern
"outgoing"or"incoming".- result
A result dict from
identify_communication_patterns(). IfNone, readcc.patterns[pattern](raising if it has not been computed).- figsize
Figure size.
- cmap
Matplotlib colormap (default
"Spectral_r"≈ CellChat’s reversed Spectral).- title
Overall figure title.
Returns¶
matplotlib.figure.Figure
Raises¶
- ValueError
If no pattern result is available for
pattern.
Pathway Similarity & Clustering (manifold)¶
Functional/structural similarity between signaling-pathway networks, UMAP
embedding, and clustering (CellChat computeNetSimilarity / netEmbedding /
netClustering).
- sceleto.interaction.compute_net_similarity(cc, *, slot: str = 'netP', type: str = 'functional', k: int | None = None, thresh: float | None = None) DataFrame[source]¶
Pairwise similarity between per-pathway signaling networks.
Port of CellChat’s
computeNetSimilarity(analysis.R). Builds annPathway × nPathwaysimilarity matrix over the K×K per-pathway networks incc.netP['prob'], then smooths it with a shared-nearest-neighbor graph.Parameters¶
- cc
CellCommobject withcc.netP['prob'](K×K×nPathway) andcc.netP['pathways']set bycompute_communication_pathway.- slot
Slot name to read the prob array from (default
"netP"); kept for API parity with R. Only"netP"is supported.- type
"functional"(Jaccard overlap of binarized networks) or"structural"(1 − D-measure; see_net_d_structure()).- k
kNN neighborhood for SNN smoothing. Defaults to
ceil(sqrt(nPathway))(+1 ifnPathway > 25), as in R.- thresh
Optional fraction in
[0, 0.25]: interactions below this quantile of the non-zero prob values are zeroed before similarity is computed (R’sthresh).
Returns¶
- pandas.DataFrame
The smoothed
nPathway × nPathwaysimilarity matrix, indexed and columned by pathway name. Also stored atcc.netP['similarity'][type].
Notes¶
Functional similarity is exactly R’s
sum(Gi*Gj) / sum(Gi + Gj − Gi*Gj)on the binarized (prob > 0) networks — i.e. the Jaccard index of the flattened K×K binary adjacency vectors. It is computed here withscipy.spatial.distance.pdist()(metric="jaccard") andsimilarity = 1 − distance; the full K×K matrix including the diagonal is flattened, matching R (R sums over all K² entries, diagonal included). The diagonal of the result is forced to 1 as in R.Structural similarity is
1 − DwhereDis the graph D-measure; it is best-effort faithful to R/igraph (see module Notes).
- sceleto.interaction.net_embedding(cc, *, type: str = 'functional', n_neighbors: int | None = None, min_dist: float = 0.3, metric: str = 'correlation', seed: int = 42, pathway_remove: list[str] | None = None, **umap_kwargs) DataFrame[source]¶
UMAP embedding of the pathway similarity matrix (R
netEmbedding).Runs 2-D UMAP on the similarity matrix (each pathway’s similarity row is its feature vector), reproducing CellChat’s
runUMAPdefaults (metric="correlation",min_dist=0.3,n_neighbors=ceil(sqrt(n))+1,seed=42).Parameters¶
- cc
CellCommobject; requirescc.netP['similarity'][type]fromcompute_net_similarity().- type
"functional"or"structural".- n_neighbors
UMAP neighborhood size. Defaults to
ceil(sqrt(nPathway)) + 1(R). Must be smaller than the number of pathways.- min_dist
UMAP
min_dist(default 0.3, as in R).- metric
UMAP metric (default
"correlation", matching R’srunUMAP).- seed
Random seed (R uses 42).
- pathway_remove
Pathway names to drop before embedding. If
None(default), R’s rule is applied: pathways whose similarity column sums to exactly 1 (i.e. only self-similar, disconnected from every other pathway) are removed.- **umap_kwargs
Extra keyword arguments forwarded to
umap.UMAP.
Returns¶
- pandas.DataFrame
nPathway × 2embedding (columnsUMAP1,UMAP2), indexed by pathway name. Also stored atcc.netP['embedding'][type].
Raises¶
- ValueError
If fewer than 3 pathways remain (UMAP requires
n_neighbors < nwithn_neighbors >= 2, so a meaningful embedding needsn >= 3).
Notes¶
UMAP requires
n_neighbors < n_samples. When the requested/derivedn_neighborsis too large for the (possibly reduced) pathway set it is clamped ton − 1with a verbose note, rather than raising.
- sceleto.interaction.net_clustering(cc, *, type: str = 'functional', k: int | None = None, method: str = 'kmeans', k_eigen: int | None = None, n_init: int = 10, seed: int = 0) Series[source]¶
Cluster pathways in the similarity embedding (R
netClustering).Parameters¶
- cc
CellCommobject; requirescc.netP['embedding'][type]fromnet_embedding().- type
"functional"or"structural".- k
Number of clusters. If
Noneandmethod="kmeans",kis chosen automatically via the Laplacian eigengap of the similarity matrix (R uses a consensus-k-means eigengap; here the eigengap is taken directly on the SNN-smoothed similarity — see Notes).- method
"kmeans"(sklearn.cluster.KMeans) or"spectral"(sklearn.cluster.SpectralClustering, normalized-Laplacian eigenvectors).- k_eigen
Number of eigenvectors for spectral clustering (default =
k).- n_init
k-means restarts (R uses
nstart=10).- seed
Random seed.
Returns¶
- pandas.Series
Pathway → integer cluster label (1-based, matching R). Also stored at
cc.netP['clustering'][type].
Notes¶
R’s automatic
kruns k-means fork = 2..min(N-1, 10), builds a consensus co-clustering matrix and takes its Laplacian eigengap. We simplify to a single eigengap computation on the SNN-smoothed similarity matrix (_eigengap_k()), which uses the same normalized-Laplacian / largest-eigengap rule and gives the same cluster count in the typical case. Pass an explicitkto bypass this.
- sceleto.interaction.plot_net_embedding(cc, *, type: str = 'functional', ax=None, figsize: tuple[float, float] = (6, 6), label: bool = True, font_size: int = 8, point_size: float = 60.0, title: str | None = None)[source]¶
Scatter of the pathway embedding colored by cluster (R
netVisual_embedding).Parameters¶
- cc
CellCommobject; requirescc.netP['embedding'][type](fromnet_embedding()) and, for coloring,cc.netP['clustering'][type](fromnet_clustering()).- type
"functional"or"structural".- ax
Existing matplotlib axes to draw on; a new figure is created if
None.- figsize
Figure size when creating a new figure.
- label
Annotate each point with its pathway name.
- font_size
Font size for the pathway labels.
- point_size
Scatter marker size.
- title
Optional axes title.
Returns¶
- matplotlib.figure.Figure
The figure containing the embedding scatter.
Multi-dataset Comparison¶
Compare communication across conditions (e.g. disease vs normal). Build per-
condition CellComm objects, then wrap them in
MultiCellComm to compare total interactions, rank
pathways by differential information flow (with a Wilcoxon test), and compute
differential networks.
- class sceleto.interaction.MultiCellComm(objects: Sequence, names: Sequence[str] | None = None)[source]¶
Bases:
objectCompare communication across multiple
CellCommdatasets.Parameters¶
- objects
The per-condition
CellCommobjects, each already run throughcompute_communication(+aggregatefor count/weight comparisons, +compute_communication_pathwayfor pathway ranking).- names
Dataset names (e.g.
["NL", "LS"]). Defaults toDataset1..N.
- compare_interactions(measure: str = 'count') DataFrame[source]¶
Total interactions (
count) or strength (weight) per dataset.Requires
CellComm.aggregate()on each object.Returns¶
- pd.DataFrame
Columns
dataset,value.
- diff_interaction(measure: str = 'count', *, comparison: tuple[int, int] = (0, 1), remove_isolate: bool = False, top: float = 1.0) DataFrame[source]¶
Differential K×K matrix
net[ds2] - net[ds1](netVisual_diffInteraction).Positive entries = increased in the second dataset.
Parameters¶
- measure
"count"or"weight".- comparison
(i, j)dataset indices; the result isds_j - ds_i.- remove_isolate
Drop groups that are all-zero in the differential.
- top
Keep only the top fraction by magnitude (
1.0keeps all).
Returns¶
- pd.DataFrame
K×K differential matrix (rows=source, cols=target).
- rank_net(*, measure: str = 'weight', comparison: tuple[int, int] = (0, 1), do_stat: bool = False, paired_test: bool = True, thresh: float = 0.05, stacked: bool = False) DataFrame[source]¶
Rank pathways by information flow across datasets (
rankNetcomparison).For each dataset, information flow of a pathway = summed communication probability over all group pairs; for
measure="weight"this is transformed as-1/log(x)(CellChat’s “information flow”). Pathways absent in a dataset contribute 0.Parameters¶
- measure
"weight"(summed prob → info flow) or"count"(binarized — number of communicating group pairs per pathway).- comparison
(i, j)dataset indices to compare.- do_stat
If
True(2 datasets only), a Wilcoxon test per pathway comparing the per-group-pair prob vectors of the two conditions.- paired_test
Paired signed-rank (default) vs unpaired rank-sum. Valid because datasets share the same K cell groups.
- thresh
p-value threshold (only used when ranking the
netslot; the default pathway-levelnetPhas no p-values).- stacked
Add a per-pathway
contribution.relative= fraction across datasets.
Returns¶
- pd.DataFrame
One row per (pathway, dataset):
name,contribution,contribution.scaled,group(dataset),contribution.relative.1, andpvalues(ifdo_stat).
Spatial Constraints¶
For spatially-resolved data, build the CellComm
object with coordinates and spatial_factors={'ratio':…, 'tol':…}, then
pass interaction_range / contact_range to compute_communication. The
communication probability is constrained by spatial proximity between cell
groups.
- sceleto.interaction.compute_region_distance(coordinates: ndarray, groups, *, interaction_range: float = 250.0, ratio: float = 1.0, tol: float = 5.0, k_min: int = 10, contact_dependent: bool = True, contact_range: float | None = None, do_symmetric: bool = True) SpatialResult[source]¶
Cluster×cluster spatial distance + contact adjacency (
computeRegionDistance).Parameters¶
- coordinates
n_cells × 2array of spot/cell centroid coordinates (pixels or µm).- groups
Per-cell group labels (array/Series/Categorical); defines the K groups.
- interaction_range
Max diffusion distance (µm). Group pairs whose nearest-neighbor distance exceeds this (beyond
tol) are marked non-interacting (d = NaN).- ratio
Pixel→µm conversion (multiplies raw coordinate distances).
- tol
Tolerance (µm) added when comparing distances against the ranges (typically half the spot/cell size).
- k_min
Minimum number of neighbor spots within range for an edge to count.
- contact_dependent
If
Truebuildadj_contactusingcontact_range; else it is all ones (no contact restriction).- contact_range
Contact distance (µm) for juxtacrine signaling (required when
contact_dependent).- do_symmetric
Symmetrize the adjacency/distance (an edge needs both directions).
Returns¶
SpatialResult
- sceleto.interaction.spatial_probability_factor(d_spatial: ndarray, *, scale_distance: float = 0.01) ndarray[source]¶
Convert the cluster distance matrix into the
P.spatialfactor.Reproduces CellChat’s
distance.use=TRUEbranch:P.spatial = 1/(d_spatial*scale_distance), non-interacting pairs → 0, and the diagonal set to the max (self-signaling gets the strongest weight).Parameters¶
- d_spatial
K × Kdistance matrix fromcompute_region_distance().- scale_distance
Scale so the minimum scaled distance is in
[1, 2](CellChat guidance).
Returns¶
- np.ndarray
K × Knon-negative spatial probability factor.
Visualization¶
- sceleto.interaction.plot_network_circle(mat: ndarray, names: Sequence[str], *, ax: Axes | None = None, figsize: tuple[float, float] = (7, 7), edge_scale: float = 8.0, node_scale: float = 800.0, cmap: str | None = None, title: str | None = None) Figure[source]¶
Circular interaction diagram (
netVisual_circle).Nodes are cell groups placed on a circle; a directed edge i→j is drawn with width proportional to
mat[i, j]and colored by the sender.Parameters¶
- mat
K × Kweight/count matrix (source × target).- names
Cell-group names.
- edge_scale, node_scale
Visual scaling for edge widths and node sizes.
- sceleto.interaction.plot_heatmap(mat: ndarray, names: Sequence[str], *, ax: Axes | None = None, figsize: tuple[float, float] = (6, 5), cmap: str = 'Reds', title: str | None = None) Figure[source]¶
Sender × receiver heatmap of interaction strength (
netVisual_heatmap).
- sceleto.interaction.plot_bubble(comm: DataFrame, *, figsize: tuple[float, float] | None = None, cmap: str = 'Reds', title: str | None = None) Figure[source]¶
Bubble plot of L–R communication (
netVisual_bubble).Parameters¶
- comm
Long-form table from
CellComm.subset_communication()(columnssource,target,interaction_name,prob,pval).
- sceleto.interaction.plot_chord(mat: ndarray, names: Sequence[str], *, ax: Axes | None = None, figsize: tuple[float, float] = (7, 7), gap: float = 0.02, title: str | None = None) Figure[source]¶
Chord diagram of group→group communication (
netVisual_chord_cell).A lightweight matplotlib implementation: each cell group gets an arc on the unit circle sized by its total interaction; ribbons connect senders to receivers with width proportional to the communication weight.
- sceleto.interaction.plot_rank_net(ranking: DataFrame, *, ax: Axes | None = None, figsize: tuple[float, float] | None = None, color: str = '#4C72B0', title: str | None = None) Figure[source]¶
Horizontal bar plot of pathway information flow (
rankNet).Parameters¶
- ranking
Output of
CellComm.rank_net()— columnspathway_nameandflow, already sorted descending.
- sceleto.interaction.plot_signaling_role_heatmap(role_matrix: DataFrame, *, figsize: tuple[float, float] | None = None, cmap: str = 'OrRd', title: str | None = None) Figure[source]¶
Pathway × cell-group signaling-role heatmap (
netAnalysis_signalingRole_heatmap).Parameters¶
- role_matrix
Output of
sceleto.interaction.signaling_role_pathway()— rows = pathways, columns = cell groups.
- sceleto.interaction.plot_contribution(contrib: DataFrame, *, ax: Axes | None = None, figsize: tuple[float, float] | None = None, color: str = '#55A868', title: str | None = None) Figure[source]¶
Bar plot of each L–R pair’s contribution to a pathway (
netAnalysis_contribution).Parameters¶
- contrib
Output of
CellComm.contribution()— columnsinteraction_nameandcontribution.
- sceleto.interaction.plot_signaling_role_scatter(cc, signaling: Sequence[str] | None = None, *, thresh: float | None = None, ax: Axes | None = None, figsize: tuple[float, float] = (6, 6), dot_scale: float = 400.0, label: bool = True, font_size: int = 9, title: str | None = None) Figure[source]¶
Dominant sender/receiver 2-D scatter (
netAnalysis_signalingRole_scatter).Each cell group is a point at
(outgoing strength, incoming strength):xis the total outgoing communication (row sums of the weight matrix, i.e. the group as sender) andythe total incoming communication (column sums, the group as receiver). Dot size is proportional to the total number of inferred links (outgoing + incoming), and dot color encodes the cell group. This is CellChat’s dominant sender/receiver map.Parameters¶
- cc
A
CellCommaftercompute_communication()andaggregate()(needscc.net['weight']andcc.net['count']).- signaling
Restrict to one or more pathway names (sum over just those pathways). If
None(default) the aggregated network over all pathways is used.- thresh
p-value threshold for counting significant links in the
signaling=...path (dot size). IfNone(default) it matches the threshold used bycompute_communication_pathway(), so dot size and dot position always share the same significance cutoff. Ignored whensignaling is None.- ax
Existing axes to draw on; a new figure is created if
None.- figsize
Figure size when creating a new figure.
- dot_scale
Overall scaling of the dot area (links → point size).
- label
Annotate each point with its cell-group name.
- font_size
Font size for the point labels.
- title
Axes title.
Returns¶
matplotlib.figure.Figure
- sceleto.interaction.plot_signaling_role_network(cc, signaling: str | None = None, *, figsize: tuple[float, float] | None = None, cmap: str = 'BuGn', title: str | None = None) Figure[source]¶
4-role centrality heatmap strip (
netAnalysis_signalingRole_network).Computes the four core CellChat centrality roles — Sender (out-degree), Receiver (in-degree), Mediator (flow betweenness), Influencer (information) — per cell group for one signaling pathway (or the aggregated network) via
compute_centrality(), row-normalizes each role by its maximum (as R does withsweep(mat, 1, max, '/')), and shows theroles × cell-groupsimportance strip.Parameters¶
- cc
A
CellCommaftercompute_communication_pathway()(for a namedsignaling) or afteraggregate()(for the aggregated network whensignaling=None).- signaling
Pathway name (from
cc.netP['pathways']). IfNone(default) the aggregatedcc.net['weight']network is used.- figsize
Figure size; a sensible size is derived from the number of groups.
- cmap
Matplotlib colormap (default
"BuGn", matching R).- title
Heatmap title.
Returns¶
matplotlib.figure.Figure
- sceleto.interaction.plot_chord_gene(cc, *, sources: Sequence[str] | None = None, targets: Sequence[str] | None = None, signaling: Sequence[str] | None = None, thresh: float = 0.05, ax: Axes | None = None, figsize: tuple[float, float] = (8, 8), gap: float = 0.015, max_pairs: int = 40, font_size: int = 8, title: str | None = None) Figure[source]¶
Gene-level ligand→receptor chord diagram (
netVisual_chord_gene).Distinct from the cell-level
sceleto.interaction.plot_chord(): sectors around the circle are the ligand and receptor genes involved, and each ribbon is a significant ligand→receptor link, colored by the sending cell group. This reveals which L–R pairs drive the communication between the chosen sources and targets. Built fromsubset_communication().Parameters¶
- cc
A
CellCommaftercompute_communication().- sources, targets
Restrict to these sender / receiver cell groups (names).
Nonekeeps all.- signaling
Restrict to these signaling pathway names.
Nonekeeps all.- thresh
p-value threshold for a link to be shown.
- ax
Existing axes; a new figure is created if
None.- figsize
Figure size when creating a new figure.
- gap
Angular gap between gene sectors, as a fraction of the full circle.
- max_pairs
Cap on the number of ligand→receptor links drawn (the strongest by probability are kept) to keep the diagram legible.
- font_size
Gene-label font size.
- title
Axes title.
Returns¶
matplotlib.figure.Figure
- sceleto.interaction.plot_communication_patterns_river(cc, pattern: str = 'outgoing', *, result: dict | None = None, cutoff: float = 0.5, figsize: tuple[float, float] = (10, 7), font_size: int = 8, title: str | None = None) Figure[source]¶
Cell-groups ↔ patterns ↔ pathways alluvial diagram (
netAnalysis_river).A three-column linked-bipartite (“river”) diagram: the left column is the cell groups, the middle column the learned communication patterns, and the right column the signaling pathways. Bands connect a cell group to a pattern with width proportional to its
Wloading, and a pattern to a pathway with width proportional to itsHloading; loadings belowcutoff(after per-column scaling inidentify_communication_patterns()) are dropped.Parameters¶
- cc
A
CellComm. Usescc.patterns[pattern]unless aresultdict is passed directly.- pattern
"outgoing"or"incoming".- result
A result dict from
identify_communication_patterns(). IfNone, readcc.patterns[pattern].- cutoff
Loadings below this are treated as zero (no band drawn), matching R’s
cutoff = 0.5.- figsize
Figure size.
- font_size
Label font size.
- title
Figure title.
Returns¶
matplotlib.figure.Figure
- sceleto.interaction.plot_communication_patterns_dot(cc, pattern: str = 'outgoing', *, result: dict | None = None, axis: str = 'cell', cutoff: float | None = None, figsize: tuple[float, float] | None = None, cmap: str = 'viridis', title: str | None = None) Figure[source]¶
Communication-pattern loading dot plot (
netAnalysis_dot).A dot plot of the NMF loadings: for
axis="cell"the y-axis is cell groups and each column is a pattern with dot size/color ∝Wloading; foraxis="signaling"the y-axis is pathways with dot size/color ∝Hloading. Loadings belowcutoffare hidden.Parameters¶
- cc
A
CellComm. Usescc.patterns[pattern]unless aresultdict is passed.- pattern
"outgoing"or"incoming".- result
A result dict from
identify_communication_patterns(). IfNone, readcc.patterns[pattern].- axis
"cell"(plotW: cell groups × patterns) or"signaling"(plotH: pathways × patterns).- cutoff
Hide loadings below this. Defaults to
1 / n_patterns(as in R).- figsize
Figure size; derived from the matrix shape if
None.- cmap
Colormap for the loading value.
- title
Axes title.
Returns¶
matplotlib.figure.Figure
- sceleto.interaction.plot_net_embedding_zoom(cc, *, type: str = 'functional', cluster: int | None = None, ax: Axes | None = None, figsize: tuple[float, float] = (6, 6), label: bool = True, font_size: int = 9, point_size: float = 120.0, title: str | None = None) Figure[source]¶
Zoomed pathway-similarity embedding scatter (
netVisual_embeddingZoomIn).Same manifold as
sceleto.interaction.plot_net_embedding(), but zoomed to one cluster: only the pathways assigned toclusterare shown (with the axes scaled to that subset), so densely packed cluster members become readable. Dot size is proportional to each pathway’s total communication probability.Parameters¶
- cc
A
CellCommwithcc.netP['embedding'][type](fromnet_embedding()) andcc.netP['clustering'][type](fromnet_clustering()).- type
"functional"or"structural".- cluster
Cluster label (1-based, as returned by
net_clustering) to zoom into. IfNoneall clusters are shown (equivalent to the full embedding but with the zoom styling).- ax
Existing axes; a new figure is created if
None.- figsize
Figure size when creating a new figure.
- label
Annotate each point with its pathway name.
- font_size
Label font size.
- point_size
Base scatter marker size (scaled by communication probability).
- title
Axes title.
Returns¶
matplotlib.figure.Figure
- sceleto.interaction.plot_aggregate(cc, signaling: str, *, layout: str = 'circle', thresh: float = 0.05, ax: Axes | None = None, figsize: tuple[float, float] = (7, 7), title: str | None = None, **kwargs) Figure[source]¶
Draw one signaling pathway’s aggregated network (
netVisual_aggregate).Convenience dispatcher: given a signaling pathway name, pull its
K × Kinter-group matrix fromcc.netP['prob'][:, :, idx]and render it with the existingsceleto.interaction.plot_network_circle()(layout="circle") orsceleto.interaction.plot_chord()(layout="chord").Parameters¶
- cc
A
CellCommaftercompute_communication_pathway().- signaling
Pathway name (from
cc.netP['pathways']).- layout
"circle"or"chord".- thresh
Unused for the pathway-level matrix (already thresholded during
compute_communication_pathway); accepted for API parity.- ax
Existing axes; a new figure is created if
None.- figsize
Figure size when creating a new figure.
- title
Plot title (defaults to
"<signaling> signaling pathway network").- **kwargs
Forwarded to the underlying plotting function.
Returns¶
matplotlib.figure.Figure