PAGA graphs and paths¶
Compare connections between cell groups, then inspect expression along a supplied group order. This guide uses Scanpy’s packaged PBMC data.
Install or update with pip install --upgrade 'genome-spy-python[scanpy]'. Choose that environment as your Jupyter kernel.
import numpy as np
import scanpy as sc
import genome_spy.integrations.scanpy as gsc
Prepare the graph with Scanpy¶
Compute group connections and graph positions with Scanpy. plot=False saves the layout without drawing a plot.
pbmc = sc.datasets.pbmc68k_reduced()
sc.tl.paga(pbmc, groups="bulk_labels")
sc.pl.paga(pbmc, threshold=0.03, plot=False, random_state=0, show=False, save=False)
Plot group connections¶
Nodes represent cell groups; thicker edges show stronger connections. Hover for details, scroll to zoom and use the slider to hide weaker edges.
graph_options = dict(
pos=pbmc.uns["paga"]["pos"],
add_pos=False,
threshold=0.03,
fontsize=9,
width=560,
height=360,
zoom=True,
show=False,
)
network = gsc.pl.paga(pbmc, edge_slider=True, **graph_options)
network
Color nodes by gene expression¶
Color shows each group’s mean GNLY expression from the saved raw snapshot. Positions stay the same.
gene_network = gsc.pl.paga(pbmc, color="GNLY", **graph_options)
gene_network
Color nodes by a stored score¶
Use a numeric observation column to show its mean within each group.
score_network = gsc.pl.paga(pbmc, color="S_score", **graph_options)
score_network
Inspect graph degree¶
Color shows normalized weighted degree at the chosen edge threshold. More connected groups have higher values.
degree_network = gsc.pl.paga(pbmc, color="degree_solid", **graph_options)
degree_network
Focus on a connected component¶
A higher threshold separates this graph into components. Show the largest one while retaining the saved node positions.
component = gsc.pl.paga(
pbmc,
pos=pbmc.uns["paga"]["pos"],
add_pos=False,
threshold=0.2,
single_component=True,
fontsize=9,
width=560,
height=360,
zoom=True,
show=False,
)
component
Inspect adjacency¶
Show the connection matrix and its tree edges. Pass the stored matrices under the keys this Scanpy call expects; scroll to zoom.
pbmc.uns["connectivities"] = pbmc.uns["paga"]["connectivities"]
pbmc.uns["connectivities_tree"] = pbmc.uns["paga"]["connectivities_tree"]
adjacency = gsc.pl.paga_adjacency(
pbmc,
labels=pbmc.obs["bulk_labels"].cat.categories,
zoom="xy",
width=360,
height=300,
show=False,
)
adjacency
Inspect connections by source group¶
Each column is a source group. Blue points identify tree edges; hover for the target group and connection strength.
connectivity = gsc.pl.paga_adjacency(
pbmc,
as_heatmap=False,
labels=pbmc.obs["bulk_labels"].cat.categories,
zoom=True,
width=480,
height=280,
show=False,
)
connectivity
Compare the graph with UMAP¶
View the same groups in the stored UMAP. Scroll or pan either panel to move both; labels move apart as you zoom.
comparison = gsc.pl.paga_compare(
pbmc,
basis="umap",
palette="tableau10",
legend_fontweight="normal",
legend_loc="on data",
show_node_labels=True,
threshold=0.03,
add_pos=False,
width=280,
height=300,
zoom=True,
show=False,
)
comparison
Prepare an expression path¶
Run diffusion pseudotime in Scanpy, starting from a CD34+ cell. Choose a group order explicitly; the plot does not infer a path.
sc.tl.diffmap(pbmc, random_state=0)
pbmc.uns["iroot"] = int(np.flatnonzero(pbmc.obs["bulk_labels"] == "CD34+")[0])
sc.tl.dpt(pbmc)
path_cells = pbmc[np.isfinite(pbmc.obs["dpt_pseudotime"])]
path_nodes = ["CD34+", "CD14+ Monocyte", "Dendritic"]
path_genes = ["LYZ", "FCER1A", "CST3", "FCGR3A", "NKG7", "CD3D"]
Show the path as a heatmap¶
Smooth expression over 25 ordered cells and scale each gene to 0–1. Zoom to inspect fitted values and group labels; hover for values.
path_heatmap = gsc.pl.paga_path(
path_cells,
nodes=path_nodes,
keys=path_genes,
n_avg=25,
normalize_to_zero_one=True,
zoom="xy",
show_values=True,
ruler=True,
width=500,
height=250,
show=False,
)
path_heatmap
Show the same path as lines¶
Use the same cells, genes and smoothing. Choose a gene from the menu to emphasize its profile.
path_lines = gsc.pl.paga_path(
path_cells,
nodes=path_nodes,
keys=path_genes,
n_avg=25,
normalize_to_zero_one=True,
as_heatmap=False,
zoom="xy",
series_select=True,
ruler=True,
width=500,
height=250,
show=False,
)
path_lines
Data use and provenance
The 700-cell Scanpy PBMC subset comes from 10x Genomics PBMC68k, licensed CC BY 4.0. Credit 10x Genomics and Scanpy’s contributors. The supplied neighbor graph and UMAP are retained. Scanpy computes PAGA, graph positions and pseudotime explicitly above. The page reads prepared inputs; the notebook runs those steps in Python.