Trajectory Inference with StaVIA#
If you use StaVIA in your research, please cite:
StaVIA: Spatio-Temporal Latent Embeddings and Vector field Inference for Collective Cell Migrations.
Paper: <https://www.biorxiv.org/content/10.1101/2024.07.04.601964v1
Code: ShobiStassen/VIA
Documentation: https://pyvia.readthedocs.io/en/latest/Atlas view examples.html
%matplotlib inline
import numpy as np
import pandas as pd
import scanpy as sc
import scvelo as scv
import anndata as ad
import omicverse as ov
from anndata import AnnData
from omicverse.external import VIA
import matplotlib.pyplot as plt
ov.plot_set()
🔬 Starting plot initialization...
🧬 Detecting GPU devices…
✅ Apple Silicon MPS detected
• [MPS] Apple Silicon GPU - Metal Performance Shaders available
____ _ _ __
/ __ \____ ___ (_)___| | / /__ _____________
/ / / / __ `__ \/ / ___/ | / / _ \/ ___/ ___/ _ \
/ /_/ / / / / / / / /__ | |/ / __/ / (__ ) __/
\____/_/ /_/ /_/_/\___/ |___/\___/_/ /____/\___/
🔖 Version: 2.2.1rc1 📚 Tutorials: https://omicverse.readthedocs.io/
✅ plot_set complete.
Load and preprocess the original tutorial data#
This notebook keeps the dentate gyrus neurogenesis dataset used by the original StaVIA tutorial. The dataset contains multiple neurogenesis-related cell populations and is suitable for demonstrating branching trajectories, lineage probabilities, and gene dynamics.
adata = scv.datasets.dentategyrus()
adata
AnnData object with n_obs × n_vars = 2930 × 13913
obs: 'clusters', 'age(days)', 'clusters_enlarged'
uns: 'clusters_colors'
obsm: 'X_umap'
layers: 'ambiguous', 'spliced', 'unspliced'
adata = ov.pp.preprocess(adata, mode="shiftlog|pearson", n_HVGs=2000)
adata.raw = adata
adata = adata[:, adata.var.highly_variable_features].copy()
ov.pp.scale(adata)
ov.pp.pca(adata, layer="scaled", n_pcs=50)
🔍 [2026-05-23 03:41:47] Running preprocessing in 'cpu' mode...
Begin robust gene identification
After filtration, 13264/13913 genes are kept.
Among 13264 genes, 13189 genes are robust.
✅ Robust gene identification completed successfully.
Begin size normalization: shiftlog and HVGs selection pearson
🔍 Count Normalization:
Target sum: 500000.0
Exclude highly expressed: True
Max fraction threshold: 0.2
⚠️ Excluding 4 highly-expressed genes from normalization computation
Excluded genes: ['Hba-a1', 'Malat1', 'Ptgds', 'Hbb-bt']
✅ Count Normalization Completed Successfully!
✓ Processed: 2,930 cells × 13,189 genes
✓ Runtime: 0.05s
🔍 Highly Variable Genes Selection (Experimental):
Method: pearson_residuals
Target genes: 2,000
Theta (overdispersion): 100
✅ Experimental HVG Selection Completed Successfully!
✓ Selected: 2,000 highly variable genes out of 13,189 total (15.2%)
✓ Results added to AnnData object:
• 'highly_variable': Boolean vector (adata.var)
• 'highly_variable_rank': Float vector (adata.var)
• 'highly_variable_nbatches': Int vector (adata.var)
• 'highly_variable_intersection': Boolean vector (adata.var)
• 'means': Float vector (adata.var)
• 'variances': Float vector (adata.var)
• 'residual_variances': Float vector (adata.var)
Time to analyze data in cpu: 0.60 seconds.
✅ Preprocessing completed successfully.
Added:
'highly_variable_features', boolean vector (adata.var)
'means', float vector (adata.var)
'variances', float vector (adata.var)
'residual_variances', float vector (adata.var)
'counts', raw counts layer (adata.layers)
End of size normalization: shiftlog and HVGs selection pearson
╭─ SUMMARY: preprocess ──────────────────────────────────────────────╮
│ Duration: 0.6525s │
│ Shape: 2,930 x 13,913 -> 2,930 x 13,189 │
│ │
│ CHANGES DETECTED │
│ ──────────────── │
│ ● VAR │ ✚ highly_variable (bool) │
│ │ ✚ highly_variable_features (bool) │
│ │ ✚ highly_variable_rank (float) │
│ │ ✚ means (float) │
│ │ ✚ n_cells (int) │
│ │ ✚ percent_cells (float) │
│ │ ✚ residual_variances (float) │
│ │ ✚ robust (bool) │
│ │ ✚ variances (float) │
│ │
│ ● UNS │ ✚ REFERENCE_MANU │
│ │ ✚ _ov_provenance │
│ │ ✚ history_log │
│ │ ✚ hvg │
│ │ ✚ log1p │
│ │ ✚ status │
│ │ ✚ status_args │
│ │
│ ● LAYERS │ ✚ counts (sparse matrix, 2930x13189) │
│ │
╰────────────────────────────────────────────────────────────────────╯
╭─ SUMMARY: scale ───────────────────────────────────────────────────╮
│ Duration: 0.0212s │
│ Shape: 2,930 x 2,000 (Unchanged) │
│ │
│ CHANGES DETECTED │
│ ──────────────── │
│ ● LAYERS │ ✚ scaled (array, 2930x2000) │
│ │
╰────────────────────────────────────────────────────────────────────╯
computing PCA🔍
with n_comps=50
🖥️ Using sklearn PCA for CPU computation
🖥️ sklearn PCA backend: CPU computation
📊 PCA input data type: ArrayView, shape: (2930, 2000), dtype: float64
🔧 PCA solver used: covariance_eigh
finished✅ (3.05s)
╭─ SUMMARY: pca ─────────────────────────────────────────────────────╮
│ Duration: 3.0553s │
│ Shape: 2,930 x 2,000 (Unchanged) │
│ │
│ CHANGES DETECTED │
│ ──────────────── │
│ ● UNS │ ✚ pca │
│ │ └─ params: {'zero_center': True, 'use_highly_variable': Tr...│
│ │ ✚ scaled|original|cum_sum_eigenvalues │
│ │ ✚ scaled|original|pca_var_ratios │
│ │
│ ● OBSM │ ✚ X_pca (array, 2930x50) │
│ │ ✚ scaled|original|X_pca (array, 2930x50) │
│ │
╰────────────────────────────────────────────────────────────────────╯
ov.pp.neighbors(
adata,
use_rep="scaled|original|X_pca",
n_neighbors=15,
n_pcs=30,
)
ov.pp.umap(adata, min_dist=1)
🖥️ Using Scanpy CPU to calculate neighbors...
🔍 K-Nearest Neighbors Graph Construction:
Mode: cpu
Neighbors: 15
Method: umap
Metric: euclidean
Representation: scaled|original|X_pca
PCs used: 30
🔍 Computing neighbor distances...
🔍 Computing connectivity matrix...
💡 Using UMAP-style connectivity
✓ Graph is fully connected
✅ KNN Graph Construction Completed Successfully!
✓ Processed: 2,930 cells with 15 neighbors each
✓ Results added to AnnData object:
• 'neighbors': Neighbors metadata (adata.uns)
• 'distances': Distance matrix (adata.obsp)
• 'connectivities': Connectivity matrix (adata.obsp)
╭─ SUMMARY: neighbors ───────────────────────────────────────────────╮
│ Duration: 5.1496s │
│ Shape: 2,930 x 2,000 (Unchanged) │
│ │
│ CHANGES DETECTED │
│ ──────────────── │
│ ● UNS │ ✚ neighbors │
│ │ └─ params: {'n_neighbors': 15, 'method': 'umap', 'random_s...│
│ │
│ ● OBSP │ ✚ connectivities (sparse matrix, 2930x2930) │
│ │ ✚ distances (sparse matrix, 2930x2930) │
│ │
╰────────────────────────────────────────────────────────────────────╯
🔍 [2026-05-23 03:41:56] Running UMAP in 'cpu' mode...
🖥️ Using Scanpy CPU UMAP...
🔍 UMAP Dimensionality Reduction:
Mode: cpu
Method: umap
Components: 2
Min distance: 1
{'n_neighbors': 15, 'method': 'umap', 'random_state': 0, 'metric': 'euclidean', 'use_rep': 'scaled|original|X_pca', 'n_pcs': 30}
🔍 Computing UMAP parameters...
🔍 Computing UMAP embedding (classic method)...
✅ UMAP Dimensionality Reduction Completed Successfully!
✓ Embedding shape: 2,930 cells × 2 dimensions
✓ Results added to AnnData object:
• 'X_umap': UMAP coordinates (adata.obsm)
• 'umap': UMAP parameters (adata.uns)
✅ UMAP completed successfully.
╭─ SUMMARY: umap ────────────────────────────────────────────────────╮
│ Duration: 0.4217s │
│ Shape: 2,930 x 2,000 (Unchanged) │
│ │
│ CHANGES DETECTED │
│ ──────────────── │
│ ● UNS │ ✚ umap │
│ │ └─ params: {'a': 0.11497568273577367, 'b': 1.9292371475038...│
│ │
╰────────────────────────────────────────────────────────────────────╯
Construct and run the model#
stavia = ov.single.StaVIA(
adata,
use_rep="scaled|original|X_pca",
n_comps=30,
basis="X_umap",
cluster_key="clusters",
spatial_key=None, # 空间 AnnData 可设置为 "spatial"
time_key=None,
sample_key=None,
key_added="stavia",
root="nIPC",
knn=15,
random_seed=4,
memory=10,
num_threads=1,
n_iter_leiden=5,
num_mcmc_simulations=200,
edgepruning_clustering_resolution=0.15,
cluster_graph_pruning=0.15,
resolution_parameter=1.5,
)
stavia.fit()
v0 = stavia.model
stavia_embedding = np.asarray(adata.obsm[stavia.basis])[:, [0, 1]]
2026-05-23 03:41:58.520110 Running VIA over input data of 2930 (samples) x 30 (features)
2026-05-23 03:41:58.520196 Knngraph has 15 neighbors
2026-05-23 03:41:59.159246 Finished global pruning of 15-knn graph used for clustering at level of 0.15. Kept 43.8 % of edges.
2026-05-23 03:41:59.164576 Number of connected components used for clustergraph is 1
2026-05-23 03:41:59.192988 Commencing community detection
2026-05-23 03:41:59.304745 Finished community detection. Found 537 clusters.
2026-05-23 03:41:59.305380 Merging 496 very small clusters (<10)
2026-05-23 03:41:59.307873 Finished detecting communities. Found 41 communities
2026-05-23 03:41:59.307983 Making cluster graph. Global cluster graph pruning level: 0.15
2026-05-23 03:41:59.310461 Graph has 1 connected components before pruning
2026-05-23 03:41:59.311200 Graph has 14 connected components after pruning
2026-05-23 03:41:59.313895 Graph has 1 connected components after reconnecting
2026-05-23 03:41:59.314115 0.0% links trimmed from local pruning relative to start
2026-05-23 03:41:59.314129 55.5% links trimmed from global pruning relative to start
initial links 346 and final_links_n 346
2026-05-23 03:41:59.315522 component number 0 out of [0]
2026-05-23 03:41:59.328916 group root method
2026-05-23 03:41:59.328946 for component 0, the root is nIPC and ri nIPC
cluster 0 has majority Granule mature
cluster 1 has majority Granule immature
cluster 2 has majority Neuroblast
cluster 3 has majority Granule immature
cluster 4 has majority Granule immature
cluster 5 has majority Granule mature
cluster 6 has majority Granule mature
cluster 7 has majority Granule immature
cluster 8 has majority Microglia
cluster 9 has majority Neuroblast
cluster 10 has majority Astrocytes
cluster 11 has majority Mossy
cluster 12 has majority Granule mature
cluster 13 has majority Granule immature
cluster 14 has majority Granule immature
cluster 15 has majority OPC
cluster 16 has majority Astrocytes
cluster 17 has majority Neuroblast
cluster 18 has majority Granule mature
cluster 19 has majority Endothelial
cluster 20 has majority OL
cluster 21 has majority Radial Glia-like
cluster 22 has majority Granule mature
cluster 23 has majority Neuroblast
cluster 24 has majority Granule immature
cluster 25 has majority GABA
cluster 26 has majority Cck-Tox
cluster 27 has majority Neuroblast
cluster 28 has majority Cajal Retzius
cluster 29 has majority Neuroblast
cluster 30 has majority Granule mature
cluster 31 has majority GABA
cluster 32 has majority Granule mature
cluster 33 has majority nIPC
2026-05-23 03:41:59.334956 New root is 33 and majority nIPC
cluster 34 has majority Granule immature
cluster 35 has majority Granule mature
cluster 36 has majority Endothelial
cluster 37 has majority Granule mature
cluster 38 has majority Endothelial
cluster 39 has majority Granule immature
cluster 40 has majority Endothelial
2026-05-23 03:41:59.335428 Computing lazy-teleporting expected hitting times
2026-05-23 03:42:03.031378 Ended all multiprocesses, will retrieve and reshape
2026-05-23 03:42:03.046939 start computing walks with rw2 method
memory for rw2 hittings times 2. Using rw2 based pt
2026-05-23 03:42:06.215805 Identifying terminal clusters corresponding to unique lineages...
2026-05-23 03:42:06.215825 Closeness:[8, 10, 11, 15, 16, 19, 20, 21, 25, 28, 31, 36, 38, 40]
2026-05-23 03:42:06.215832 Betweenness:[2, 4, 5, 6, 7, 8, 10, 11, 12, 14, 15, 16, 17, 19, 20, 22, 25, 26, 28, 29, 30, 31, 33, 34, 36, 38, 39]
2026-05-23 03:42:06.215837 Out Degree:[4, 5, 7, 8, 10, 11, 14, 15, 16, 17, 20, 21, 24, 25, 26, 28, 29, 30, 31, 34, 36, 38, 40]
2026-05-23 03:42:06.215999 Terminal clusters corresponding to unique lineages in this component are [34, 4, 5, 36, 7, 8, 38, 11, 14, 19, 25, 26, 28, 29, 30, 31]
2026-05-23 03:42:06.216009 Calculating lineage probability at memory 10
2026-05-23 03:42:07.848723 Cluster or terminal cell fate 34 is reached 285.0 times
2026-05-23 03:42:07.876274 Cluster or terminal cell fate 4 is reached 422.0 times
2026-05-23 03:42:07.904651 Cluster or terminal cell fate 5 is reached 103.0 times
2026-05-23 03:42:07.936983 Cluster or terminal cell fate 36 is reached 2.0 times
2026-05-23 03:42:07.953386 Cluster or terminal cell fate 7 is reached 836.0 times
2026-05-23 03:42:07.982691 Cluster or terminal cell fate 8 is reached 2.0 times
2026-05-23 03:42:08.011524 38 cluster/state is never reached. try increase number of KNN (which will increase number of edges) or try to increase the value of jac_std_global and cluster_graph_pruning which will lower edge pruning
2026-05-23 03:42:08.038857 Cluster or terminal cell fate 11 is reached 55.0 times
2026-05-23 03:42:08.064817 Cluster or terminal cell fate 14 is reached 471.0 times
2026-05-23 03:42:08.094192 19 cluster/state is never reached. try increase number of KNN (which will increase number of edges) or try to increase the value of jac_std_global and cluster_graph_pruning which will lower edge pruning
2026-05-23 03:42:08.122250 Cluster or terminal cell fate 25 is reached 41.0 times
2026-05-23 03:42:08.150453 Cluster or terminal cell fate 26 is reached 43.0 times
2026-05-23 03:42:08.179153 Cluster or terminal cell fate 28 is reached 1.0 times
2026-05-23 03:42:08.195867 Cluster or terminal cell fate 29 is reached 763.0 times
2026-05-23 03:42:08.223063 Cluster or terminal cell fate 30 is reached 178.0 times
2026-05-23 03:42:08.250671 Cluster or terminal cell fate 31 is reached 42.0 times
2026-05-23 03:42:08.256473 There are (16) terminal clusters corresponding to unique lineages {34: 'Granule immature', 4: 'Granule immature', 5: 'Granule mature', 36: 'Endothelial', 7: 'Granule immature', 8: 'Microglia', 38: 'Endothelial', 11: 'Mossy', 14: 'Granule immature', 19: 'Endothelial', 25: 'GABA', 26: 'Cck-Tox', 28: 'Cajal Retzius', 29: 'Neuroblast', 30: 'Granule mature', 31: 'GABA'}
2026-05-23 03:42:08.256519 Begin projection of pseudotime and lineage likelihood
2026-05-23 03:42:08.553971 Cluster graph layout based on forward biasing
2026-05-23 03:42:08.555818 Starting make edgebundle viagraph...
2026-05-23 03:42:10.624382 Make via clustergraph edgebundle
2026-05-23 03:42:10.784876 Hammer dims: Nodes shape: (41, 2) Edges shape: (154, 3)
2026-05-23 03:42:10.785206 Graph has 1 connected components before pruning
2026-05-23 03:42:10.785870 Graph has 17 connected components after pruning
2026-05-23 03:42:10.789041 Graph has 1 connected components after reconnecting
2026-05-23 03:42:10.789217 51.3% links trimmed from local pruning relative to start
2026-05-23 03:42:10.789229 54.5% links trimmed from global pruning relative to start
initial links 154 and final_links_n 75
2026-05-23 03:42:10.790419 Start making edgebundle milestone with 150 milestones...This can be recomputed with make_edgebundle_milestone()
2026-05-23 03:42:10.790443 Start finding milestones
2026-05-23 03:42:11.179825 End milestones with 150
2026-05-23 03:42:11.179901 Will use via-pseudotime for edges, otherwise consider providing a list of numeric labels (single cell level) or via_object
2026-05-23 03:42:11.182473 Recompute weights
2026-05-23 03:42:11.194560 pruning milestone graph based on recomputed weights
2026-05-23 03:42:11.195179 Graph has 1 connected components before pruning
2026-05-23 03:42:11.195457 Graph has 4 connected components after pruning
2026-05-23 03:42:11.196548 Graph has 1 connected components after reconnecting
2026-05-23 03:42:11.197007 66.4% links trimmed from global pruning relative to start
2026-05-23 03:42:11.197023 regenerate igraph on pruned edges
2026-05-23 03:42:11.200202 Setting numeric label as single cell pseudotime for coloring edges
2026-05-23 03:42:11.205151 Making smooth edges
REMEMBER TO RE-INCLUDE the PLT.SHOW HERE - COMMENTING IT OUT FOR NOW
2026-05-23 03:42:11.523012 Time elapsed 12.7 seconds
StaVIA graph structure and pseudotime#
fig, ax, ax1 = VIA.core.plot_piechart_viagraph(
via_object=v0,
dpi=80,
ax_text=False,
show_legend=False,
)
fig.set_size_inches(8, 4)
plt.show()
StaVIA trajectory projection#
fig, ax, ax1 = VIA.core.plot_trajectory_curves(
via_object=v0,
embedding=stavia_embedding,
dpi=80,
draw_all_curves=False,
)
fig.set_size_inches(10, 5)
plt.show()
2026-05-23 03:42:18.522921 Super cluster 4 is a super terminal with sub_terminal cluster 34
2026-05-23 03:42:18.524379 Super cluster 5 is a super terminal with sub_terminal cluster 4
2026-05-23 03:42:18.524405 Super cluster 7 is a super terminal with sub_terminal cluster 5
2026-05-23 03:42:18.524421 Super cluster 8 is a super terminal with sub_terminal cluster 36
2026-05-23 03:42:18.524438 Super cluster 11 is a super terminal with sub_terminal cluster 7
2026-05-23 03:42:18.524454 Super cluster 14 is a super terminal with sub_terminal cluster 8
2026-05-23 03:42:18.524484 Super cluster 19 is a super terminal with sub_terminal cluster 38
2026-05-23 03:42:18.524506 Super cluster 25 is a super terminal with sub_terminal cluster 11
2026-05-23 03:42:18.524522 Super cluster 26 is a super terminal with sub_terminal cluster 14
2026-05-23 03:42:18.524538 Super cluster 28 is a super terminal with sub_terminal cluster 19
2026-05-23 03:42:18.524557 Super cluster 29 is a super terminal with sub_terminal cluster 25
2026-05-23 03:42:18.524587 Super cluster 30 is a super terminal with sub_terminal cluster 26
2026-05-23 03:42:18.524604 Super cluster 31 is a super terminal with sub_terminal cluster 28
2026-05-23 03:42:18.524621 Super cluster 34 is a super terminal with sub_terminal cluster 29
2026-05-23 03:42:18.524638 Super cluster 36 is a super terminal with sub_terminal cluster 30
2026-05-23 03:42:18.524653 Super cluster 38 is a super terminal with sub_terminal cluster 31
StaVIA lineage probabilities#
Following the probabilistic pathways section in t_via.ipynb, we first show all terminal lineage probabilities and then inspect the first two terminal lineages separately.
fig, axs = VIA.core.plot_sc_lineage_probability(
via_object=v0,
embedding=stavia_embedding,
dpi=90,
)
fig.set_size_inches(8, 8)
plt.show()
2026-05-23 03:42:18.907709 Marker_lineages: [34, 4, 5, 36, 7, 8, 38, 11, 14, 19, 25, 26, 28, 29, 30, 31]
2026-05-23 03:42:18.908332 The number of components in the original full graph is 1
2026-05-23 03:42:18.908346 For downstream visualization purposes we are also constructing a low knn-graph
2026-05-23 03:42:22.112467 Check sc pb 1.0000000000000002
f getting majority comp
2026-05-23 03:42:22.136347 Cluster path on clustergraph starting from Root Cluster 33 to Terminal Cluster 34: [33, 23, 27, 9, 1, 3, 24, 18, 37, 6, 34]
2026-05-23 03:42:22.136364 Cluster path on clustergraph starting from Root Cluster 33 to Terminal Cluster 4: [33, 23, 27, 9, 1, 3, 24, 18, 37, 6, 22, 4]
2026-05-23 03:42:22.136371 Cluster path on clustergraph starting from Root Cluster 33 to Terminal Cluster 5: [33, 23, 27, 9, 1, 3, 24, 18, 37, 0, 5]
2026-05-23 03:42:22.136377 Cluster path on clustergraph starting from Root Cluster 33 to Terminal Cluster 36: [33, 23, 21, 40, 36]
2026-05-23 03:42:22.136383 Cluster path on clustergraph starting from Root Cluster 33 to Terminal Cluster 7: [33, 23, 27, 9, 1, 3, 7]
2026-05-23 03:42:22.136388 Cluster path on clustergraph starting from Root Cluster 33 to Terminal Cluster 8: [33, 23, 21, 40, 36, 8]
2026-05-23 03:42:22.136394 Cluster path on clustergraph starting from Root Cluster 33 to Terminal Cluster 38: [33, 23, 21, 40, 19, 38]
2026-05-23 03:42:22.136407 Cluster path on clustergraph starting from Root Cluster 33 to Terminal Cluster 11: [33, 23, 27, 9, 29, 11]
2026-05-23 03:42:22.136413 Cluster path on clustergraph starting from Root Cluster 33 to Terminal Cluster 14: [33, 23, 27, 9, 1, 3, 24, 18, 35, 14]
2026-05-23 03:42:22.136419 Cluster path on clustergraph starting from Root Cluster 33 to Terminal Cluster 19: [33, 23, 21, 40, 19]
2026-05-23 03:42:22.136424 Cluster path on clustergraph starting from Root Cluster 33 to Terminal Cluster 25: [33, 23, 27, 9, 1, 3, 24, 26, 31, 25]
2026-05-23 03:42:22.136429 Cluster path on clustergraph starting from Root Cluster 33 to Terminal Cluster 26: [33, 23, 27, 9, 1, 3, 24, 26]
2026-05-23 03:42:22.136435 Cluster path on clustergraph starting from Root Cluster 33 to Terminal Cluster 28: [33, 23, 21, 40, 28]
2026-05-23 03:42:22.136439 Cluster path on clustergraph starting from Root Cluster 33 to Terminal Cluster 29: [33, 23, 27, 9, 29]
2026-05-23 03:42:22.136445 Cluster path on clustergraph starting from Root Cluster 33 to Terminal Cluster 30: [33, 23, 27, 9, 1, 3, 24, 18, 35, 12, 30]
2026-05-23 03:42:22.136450 Cluster path on clustergraph starting from Root Cluster 33 to Terminal Cluster 31: [33, 23, 27, 9, 1, 3, 24, 26, 31]
setting vmin to 0.0
2026-05-23 03:42:22.179057 Revised Cluster level path on sc-knnGraph from Root Cluster 33 to Terminal Cluster 34 along path: [16, 16, 10, 21, 40, 18, 14, 14, 14]
setting vmin to 0.0
2026-05-23 03:42:22.186226 Revised Cluster level path on sc-knnGraph from Root Cluster 33 to Terminal Cluster 4 along path: [16, 16, 10, 21, 40, 18, 4, 4]
setting vmin to 0.0
2026-05-23 03:42:22.192922 Revised Cluster level path on sc-knnGraph from Root Cluster 33 to Terminal Cluster 5 along path: [16, 16, 10, 21, 40, 18, 32, 5, 5]
setting vmin to 0.0
2026-05-23 03:42:22.199331 Revised Cluster level path on sc-knnGraph from Root Cluster 33 to Terminal Cluster 36 along path: [16, 16, 10, 21, 40, 36, 36]
setting vmin to 0.0
2026-05-23 03:42:22.206620 Revised Cluster level path on sc-knnGraph from Root Cluster 33 to Terminal Cluster 7 along path: [16, 16, 10, 21, 40, 18, 7, 7, 7, 7]
setting vmin to 0.0
2026-05-23 03:42:22.212950 Revised Cluster level path on sc-knnGraph from Root Cluster 33 to Terminal Cluster 8 along path: [16, 16, 10, 21, 40, 36, 8, 8, 8]
setting vmin to 0.0
2026-05-23 03:42:22.219294 Revised Cluster level path on sc-knnGraph from Root Cluster 33 to Terminal Cluster 38 along path: [16, 16, 10, 21, 40, 19, 38, 38]
setting vmin to 0.0
2026-05-23 03:42:22.226233 Revised Cluster level path on sc-knnGraph from Root Cluster 33 to Terminal Cluster 11 along path: [16, 16, 10, 21, 40, 18, 7, 11, 11, 11, 11]
setting vmin to 0.0
2026-05-23 03:42:22.232608 Revised Cluster level path on sc-knnGraph from Root Cluster 33 to Terminal Cluster 14 along path: [16, 16, 10, 21, 40, 18, 6, 6]
setting vmin to 0.0
2026-05-23 03:42:22.238817 Revised Cluster level path on sc-knnGraph from Root Cluster 33 to Terminal Cluster 19 along path: [16, 16, 10, 21, 40, 19, 19, 19]
setting vmin to 0.0
2026-05-23 03:42:22.245684 Revised Cluster level path on sc-knnGraph from Root Cluster 33 to Terminal Cluster 25 along path: [16, 16, 16, 16, 21, 23, 33, 27, 17, 17, 17]
setting vmin to 0.0
2026-05-23 03:42:22.252034 Revised Cluster level path on sc-knnGraph from Root Cluster 33 to Terminal Cluster 26 along path: [16, 16, 16, 16, 21, 23, 2, 2, 2]
setting vmin to 0.0
2026-05-23 03:42:22.258201 Revised Cluster level path on sc-knnGraph from Root Cluster 33 to Terminal Cluster 28 along path: [16, 16, 10, 21, 40, 28, 28, 28]
setting vmin to 0.0
2026-05-23 03:42:22.265251 Revised Cluster level path on sc-knnGraph from Root Cluster 33 to Terminal Cluster 29 along path: [16, 16, 16, 16, 21, 23, 33, 29, 29]
setting vmin to 0.0
2026-05-23 03:42:22.271397 Revised Cluster level path on sc-knnGraph from Root Cluster 33 to Terminal Cluster 30 along path: [16, 16, 10, 21, 40, 18, 5, 5]
setting vmin to 0.0
2026-05-23 03:42:22.278099 Revised Cluster level path on sc-knnGraph from Root Cluster 33 to Terminal Cluster 31 along path: [16, 16, 16, 16, 21, 23, 2, 31, 31, 31]
marker_lineages = list(v0.terminal_clusters)[:2]
fig, axs = VIA.core.plot_sc_lineage_probability(
via_object=v0,
embedding=stavia_embedding,
marker_lineages=marker_lineages,
dpi=90,
)
fig.set_size_inches(6, 3)
plt.show()
2026-05-23 03:42:22.768337 Marker_lineages: [34, 4]
2026-05-23 03:42:22.768924 The number of components in the original full graph is 1
2026-05-23 03:42:22.768935 For downstream visualization purposes we are also constructing a low knn-graph
2026-05-23 03:42:25.981370 Check sc pb 1.0000000000000002
f getting majority comp
2026-05-23 03:42:26.004326 Cluster path on clustergraph starting from Root Cluster 33 to Terminal Cluster 34: [33, 23, 27, 9, 1, 3, 24, 18, 37, 6, 34]
2026-05-23 03:42:26.004345 Cluster path on clustergraph starting from Root Cluster 33 to Terminal Cluster 4: [33, 23, 27, 9, 1, 3, 24, 18, 37, 6, 22, 4]
setting vmin to 0.0
2026-05-23 03:42:26.015852 Revised Cluster level path on sc-knnGraph from Root Cluster 33 to Terminal Cluster 34 along path: [16, 16, 10, 21, 40, 18, 14, 14, 14]
setting vmin to 0.0
2026-05-23 03:42:26.022199 Revised Cluster level path on sc-knnGraph from Root Cluster 33 to Terminal Cluster 4 along path: [16, 16, 10, 21, 40, 18, 4, 4]
StaVIA lineage path atlas view#
lineage_pathway = list(v0.terminal_clusters)[:2]
fig, axs = VIA.core.plot_atlas_view(
via_object=v0,
dpi=80,
lineage_pathway=lineage_pathway,
fontsize_title=12,
fontsize_labels=12,
)
fig.set_size_inches(12, 4)
plt.show()
StaVIA stream plots#
We show stream plots colored by annotation and by pseudotime.
fig, ax = VIA.core.via_streamplot(
via_object=v0,
embedding=stavia_embedding,
dpi=100,
density_grid=1.0,
density_stream=2.5,
scatter_size=18,
scatter_alpha=0.28,
linewidth=0.8,
)
fig.set_size_inches(5, 5)
plt.show()
fig, ax = VIA.core.via_streamplot(
via_object=v0,
embedding=stavia_embedding,
dpi=100,
density_grid=1.0,
density_stream=2.5,
scatter_size=18,
scatter_alpha=0.28,
linewidth=0.8,
color_scheme="time",
min_mass=1,
cutoff_perc=5,
marker_edgewidth=0.1,
smooth_transition=1,
smooth_grid=0.5,
)
fig.set_size_inches(5, 5)
plt.show()
Gene / feature graph visualization#
Selected genes are first smoothed with the fitted VIA graph in a MAGIC-like manner and then shown at the cluster level.
stavia_marker_genes = [
gene
for gene in ["Sox2", "Mki67", "Dcx", "Neurod1", "Stmn2", "Prox1"]
if gene in adata.raw.var_names
]
df_gene = adata.raw[:, stavia_marker_genes].to_adata().to_df()
df_magic = v0.do_impute(
df_gene,
magic_steps=3,
gene_list=stavia_marker_genes,
)
shape of transition matrix raised to power 3 (2930, 2930)
StaVIA lineage gene dynamics#
Following the Gene Dynamics section in t_via.ipynb, VIA estimates gene dynamics along detected terminal lineages. We first show native VIA trend curves and heatmaps, then compare them with the general OmicVerse dynamic trend and dynamic heatmap workflow.
fig, axs = VIA.core.get_gene_expression(
via_object=v0,
gene_exp=df_magic[stavia_marker_genes],
marker_genes=stavia_marker_genes,
dpi=80,
figsize=(10, 4),
ncols=3,
legend_loc="right",
)
plt.show()
Area under curve Sox2 for branch Granule immature is 0.04555084777559561
Area under curve Sox2 for branch Granule immature is 0.045407271658158
Area under curve Sox2 for branch Granule mature is 0.01740516033550336
Area under curve Sox2 for branch Endothelial is 0.4365656783049289
Area under curve Sox2 for branch Granule immature is 0.03156509166196033
Area under curve Sox2 for branch Microglia is 0.4495056942016664
Area under curve Sox2 for branch Endothelial is 0.6048382824997743
Area under curve Sox2 for branch Mossy is 0.07180963739563352
Area under curve Sox2 for branch Granule immature is 0.04269178436885223
Area under curve Sox2 for branch Endothelial is 0.595204745491246
Area under curve Sox2 for branch GABA is 0.27454546430816434
Area under curve Sox2 for branch Cck-Tox is 0.03393808276100714
Area under curve Sox2 for branch Cajal Retzius is 0.3018231646426621
Area under curve Sox2 for branch Neuroblast is 0.03412303064142045
Area under curve Sox2 for branch Granule mature is 0.017745862236227043
Area under curve Sox2 for branch GABA is 0.06261071335183203
Area under curve Mki67 for branch Granule immature is 0.09034506497399783
Area under curve Mki67 for branch Granule immature is 0.09205147263180798
Area under curve Mki67 for branch Granule mature is 0.08854877619409621
Area under curve Mki67 for branch Endothelial is 0.00682820879664287
Area under curve Mki67 for branch Granule immature is 0.0955369176930149
Area under curve Mki67 for branch Microglia is 0.005102516232228827
Area under curve Mki67 for branch Endothelial is 0.00029323206406245655
Area under curve Mki67 for branch Mossy is 0.08644358484456853
Area under curve Mki67 for branch Granule immature is 0.0930850676340502
Area under curve Mki67 for branch Endothelial is 0.00040806315589284297
Area under curve Mki67 for branch GABA is 0.08492206396316215
Area under curve Mki67 for branch Cck-Tox is 0.07780565932132545
Area under curve Mki67 for branch Cajal Retzius is 0.003101291820012787
Area under curve Mki67 for branch Neuroblast is 0.07548092958536806
Area under curve Mki67 for branch Granule mature is 0.09545907843340447
Area under curve Mki67 for branch GABA is 0.0816514398903189
Area under curve Dcx for branch Granule immature is 0.5600034953433524
Area under curve Dcx for branch Granule immature is 0.5575764385598792
Area under curve Dcx for branch Granule mature is 0.585268527051407
Area under curve Dcx for branch Endothelial is 0.018151451059503495
Area under curve Dcx for branch Granule immature is 0.650718297123587
Area under curve Dcx for branch Microglia is 0.014293007292746351
Area under curve Dcx for branch Endothelial is 0.0040755790307366755
Area under curve Dcx for branch Mossy is 0.5985991773343364
Area under curve Dcx for branch Granule immature is 0.5595470750905737
Area under curve Dcx for branch Endothelial is 0.004838926637865078
Area under curve Dcx for branch GABA is 0.724112072458108
Area under curve Dcx for branch Cck-Tox is 0.5207230862792283
Area under curve Dcx for branch Cajal Retzius is 0.02635524216169538
Area under curve Dcx for branch Neuroblast is 0.47057998206697504
Area under curve Dcx for branch Granule mature is 0.5894810716070027
Area under curve Dcx for branch GABA is 0.6465835893490894
Area under curve Stmn2 for branch Granule immature is 2.8383767039934504
Area under curve Stmn2 for branch Granule immature is 2.847803822475739
Area under curve Stmn2 for branch Granule mature is 2.911185556543988
Area under curve Stmn2 for branch Endothelial is 0.0966190501856051
Area under curve Stmn2 for branch Granule immature is 3.245992687762593
Area under curve Stmn2 for branch Microglia is 0.09391954819969517
Area under curve Stmn2 for branch Endothelial is 0.14685710778947692
Area under curve Stmn2 for branch Mossy is 2.8711828615219828
Area under curve Stmn2 for branch Granule immature is 2.875845353342913
Area under curve Stmn2 for branch Endothelial is 0.1499565135729379
Area under curve Stmn2 for branch GABA is 5.112751522344148
Area under curve Stmn2 for branch Cck-Tox is 3.1615089304845037
Area under curve Stmn2 for branch Cajal Retzius is 3.036941368001442
Area under curve Stmn2 for branch Neuroblast is 1.8466784259438742
Area under curve Stmn2 for branch Granule mature is 3.049142491873102
Area under curve Stmn2 for branch GABA is 4.118711675239748
Area under curve Prox1 for branch Granule immature is 2.3954569221844135
Area under curve Prox1 for branch Granule immature is 2.4353509185420212
Area under curve Prox1 for branch Granule mature is 2.2910714290599477
Area under curve Prox1 for branch Endothelial is 0.09097517269908757
Area under curve Prox1 for branch Granule immature is 1.686737503877866
Area under curve Prox1 for branch Microglia is 0.0917367946896335
Area under curve Prox1 for branch Endothelial is 0.09175331231000933
Area under curve Prox1 for branch Mossy is 1.5763457594481136
Area under curve Prox1 for branch Granule immature is 2.4625784415863725
Area under curve Prox1 for branch Endothelial is 0.09199137612619969
Area under curve Prox1 for branch GABA is 1.8498330745857954
Area under curve Prox1 for branch Cck-Tox is 1.9309835244800033
Area under curve Prox1 for branch Cajal Retzius is 0.23284463236423042
Area under curve Prox1 for branch Neuroblast is 1.1639010734109925
Area under curve Prox1 for branch Granule mature is 2.5187810925275302
Area under curve Prox1 for branch GABA is 1.825872623208185
StaVIA lineage gene dynamics#
VIA estimates gene dynamics along detected terminal lineages. We first show native VIA trend curves and heatmaps, then compare them with the general OmicVerse dynamic trend and dynamic heatmap workflow.