Scanpy on the platform
Single-cell RNA-seq analysis with Scanpy for preprocessing, clustering, and trajectory inference.
Scanpy takes single-cell RNA-seq data from raw counts to annotated cell types and marker genes — the classical, fast, interpretable path through quality control, clustering, differential expression, and trajectory inference. Reach for it as your default for single-cell analysis when speed and interpretability matter and you don't have heavy batch effects to correct. When you do — multiple samples to integrate, or unknown cell types to annotate — pair it with scvi-tools, whose deep generative models plug into the same AnnData object. See what you can achieve for the full set.
Scanpy single-cell analysis on the platform
Scanpy is a scalable toolkit for analyzing single-cell gene expression data, built on top of the AnnData data structure. Through the platform, you can run comprehensive scRNA-seq workflows from raw counts to publication-ready visualizations -- including quality control, normalization, dimensionality reduction, clustering, differential expression, and trajectory inference.
Scanpy is the most widely used Python framework for single-cell analysis, with native support for datasets ranging from a few hundred cells to millions. It integrates tightly with the broader scverse ecosystem (scvi-tools, squidpy, muon) for advanced modeling tasks.
Citations
Wolf FA, Angerer P, Theis FJ. SCANPY: large-scale single-cell gene expression data analysis. Genome Biology. 2018;19:15. doi: 10.1186/s13059-017-1382-0
How the platform runs Scanpy
The platform runs Scanpy as a GPU-accelerated job on rapids-singlecell (cuML, cuGraph, cupy on a T4 GPU), which speeds up PCA, k-NN, UMAP, and Leiden relative to the CPU-only open-source package. You supply an AnnData .h5ad file (S3 URI or HTTPS URL) and choose one workflow:
full(default) — the complete pipeline: QC → normalize → highly variable genes → PCA → neighbors → UMAP → Leiden → differential expression.qc— quality control and filtering only.clustering— QC through Leiden and UMAP, without marker genes.de— differential expression / marker genes.
Beyond these four GPU workflows, the tool exposes CPU-based extension workflows for batch correction (harmony_integrate, scanorama_integrate, combat_correct), automated annotation (celltypist_annotate), gene-set and marker scoring (aucell_score, cosg_markers, hotspot_modules), stemness (cytotrace2_potency), and RNA velocity (scvelo_velocity).
The sections below describe the underlying Scanpy methods in depth — the platform pipeline follows this same sequence, with GPU-accelerated implementations of the compute-heavy steps.
The platform's Scanpy job focuses on the QC-to-clustering-to-markers path plus scverse extensions. Niche standalone workflows (trajectory inference, GRN, spatial clustering, cellxgene search) are handled by dedicated tools rather than this job — the trajectory and PAGA material below is background on the method, not a workflow you select here.
Technical approach
The AnnData object model
Scanpy operates on the AnnData (Annotated Data) object, which stores all information for a single-cell experiment in a structured format:
| Slot | Contents | Example |
|---|---|---|
X | Expression matrix (cells x genes) | Raw counts or normalized values |
obs | Cell-level metadata (one row per cell) | Sample ID, batch, cell type labels |
var | Gene-level metadata (one row per gene) | Gene symbols, highly variable flags |
obsm | Cell embeddings (multi-dimensional) | PCA coordinates, UMAP coordinates |
obsp | Cell-cell graphs | Nearest-neighbor connectivity matrix |
uns | Unstructured metadata | Clustering parameters, color palettes |
layers | Alternative expression matrices | Raw counts, spliced/unspliced (for RNA velocity) |
This design means a single .h5ad file captures the entire analysis state -- raw data, processed matrices, embeddings, cluster assignments, and metadata -- making results fully reproducible.
Preprocessing pipeline
Scanpy's standard preprocessing workflow follows a well-established sequence:
1. Quality control and filtering
- Filter cells by minimum gene count (default: 200 genes) to remove empty droplets
- Filter genes by minimum cell count (default: 3 cells) to remove uninformative genes
- Calculate mitochondrial gene percentages and filter cells above a threshold (default: 20%) to remove dying cells
- Optionally filter doublets using scrublet scores
2. Normalization
- Library-size normalization (
sc.pp.normalize_total): Scale each cell to a target sum (typically 10,000) so that expression values are comparable across cells with different sequencing depths - Log transformation (
sc.pp.log1p): Apply log(1+x) to stabilize variance and make the data more normally distributed - Store raw counts in
adata.layers['counts']before normalization for differential expression
3. Highly variable gene (HVG) selection
- Identify genes with high cell-to-cell variation using
sc.pp.highly_variable_genes - Typically select 2,000-5,000 HVGs to focus downstream analysis on informative genes
- Methods:
seurat(default),seurat_v3(for raw counts), orcell_ranger - HVG selection dramatically reduces dimensionality and noise without losing biological signal
4. Scaling
- Center and scale expression values to zero mean and unit variance (
sc.pp.scale) - Optionally clip extreme values (e.g.,
max_value=10) to limit the influence of outliers
Dimensionality reduction
Scanpy implements a two-stage dimensionality reduction approach:
PCA (Principal Component Analysis)
- Reduces the HVG expression matrix from ~2,000 dimensions to 50 principal components
- Captures the major axes of biological variation
- The number of informative PCs can be assessed with an elbow plot (
sc.pl.pca_variance_ratio) - Typically 30-50 PCs are used for downstream steps
Neighbor graph construction
- Builds a k-nearest neighbor (kNN) graph in PCA space using
sc.pp.neighbors - Default: 15 neighbors, Euclidean distance in PCA space
- This graph is the foundation for both clustering and visualization
UMAP and t-SNE
- UMAP (
sc.tl.umap): Produces a 2D embedding that preserves both local and global structure. Preferred for most applications. Key parameters:min_dist(compactness, default 0.5) andspread(default 1.0) - t-SNE (
sc.tl.tsne): Produces a 2D embedding optimized for local structure. Better for visually separating tight clusters, but does not preserve global distances. Key parameter:perplexity(default 30)
UMAP is generally recommended over t-SNE for exploratory analysis because it runs faster, scales better, and preserves more global structure. Use t-SNE when you need to emphasize local cluster separation for publication figures.
Clustering
Scanpy implements graph-based community detection algorithms:
Leiden algorithm (sc.tl.leiden)
- Preferred method -- produces well-connected communities with a quality guarantee
- The
resolutionparameter controls cluster granularity: lower values (0.1-0.5) yield fewer, larger clusters; higher values (1.0-2.0) yield more, smaller clusters - Default resolution: 1.0
- Operates on the kNN graph constructed during neighbor computation
Louvain algorithm (sc.tl.louvain)
- Older alternative to Leiden -- faster but can produce poorly connected communities
- Same resolution parameter semantics as Leiden
- Generally recommended to use Leiden instead unless backward compatibility is needed
Choosing resolution: Start with the default (1.0) and adjust based on biological expectations. Over-clustering is generally preferable to under-clustering -- you can always merge clusters, but splitting them requires re-running.
Differential expression
Scanpy identifies marker genes for each cluster using sc.tl.rank_genes_groups:
| Method | Description | Best For |
|---|---|---|
wilcoxon | Wilcoxon rank-sum test (default) | Most applications; robust to non-normality |
t-test | Welch's t-test | Normally distributed data, fast |
t-test_overestim_var | t-test with overestimated variance | Conservative, fewer false positives |
logreg | Logistic regression | Multi-class marker selection |
Results include log fold change, p-values, and adjusted p-values (Benjamini-Hochberg). Use the top-ranked genes per cluster to annotate cell types by cross-referencing with known marker databases (CellMarker, PanglaoDB).
Trajectory inference
Scanpy supports pseudotime and lineage analysis through several approaches:
- Diffusion pseudotime (
sc.tl.dpt): Computes pseudotime ordering based on diffusion distances in the neighbor graph. Requires specifying a root cell (typically the most undifferentiated population). - PAGA (
sc.tl.paga): Partition-based graph abstraction. Creates a coarse-grained graph of cluster connectivity, useful for identifying differentiation trajectories and transitions between cell states. - RNA velocity (via scVelo): Not built into Scanpy but integrates seamlessly. Uses spliced/unspliced RNA ratios to infer the direction of cell state transitions.
When to use Scanpy
Primary applications
- scRNA-seq quality control and analysis: The core use case. From raw 10X Genomics or Smart-seq2 data through to annotated cell types and marker genes.
- Spatial transcriptomics preprocessing: Scanpy handles the expression matrix for spatial technologies (Visium, MERFISH, Slide-seq). Use squidpy for spatial-specific analyses on top.
- Atlas-scale integration: With backed mode (
sc.read_h5ad(backed='r')), Scanpy can handle datasets with millions of cells without loading the full matrix into memory. - Comparative analysis: Compare cell populations across conditions, treatments, or time points using differential expression and composition analysis.
- Cell type annotation: Combine clustering with marker gene analysis and reference-based annotation (e.g., via Celltypist or manual curation).
Comparison with Seurat
Seurat is the primary R-based alternative to Scanpy. Key differences:
| Aspect | Scanpy (Python) | Seurat (R) |
|---|---|---|
| Language | Python | R |
| Data structure | AnnData (.h5ad) | Seurat object (.rds) |
| Scalability | Better for large datasets (>500K cells) via backed mode | Memory-limited; requires Seurat v5 disk-backed for large data |
| Ecosystem | scverse (scvi-tools, squidpy, muon) | Signac (ATAC-seq), Azimuth (reference mapping) |
| Integration methods | Harmony, BBKNN, scVI (via scvi-tools) | CCA, RPCA, Harmony |
| Visualization | Matplotlib-based (customizable but verbose) | ggplot2-based (publication-ready defaults) |
| Community | Larger in computational biology / ML | Larger in experimental biology / clinical |
Both frameworks produce comparable results for standard workflows. Choose based on your language preference and downstream ecosystem needs. Results can be converted between formats using anndata2ri or SeuratDisk.
Limitations
- Memory-intensive for large datasets: Datasets above 500,000 cells require careful memory management. Use backed mode, sparse matrices, and chunked processing. For datasets above 2 million cells, consider subsampling or using geometric sketching before full analysis.
- Limited built-in batch correction: Scanpy's native batch correction (
sc.pp.combat) is basic. For multi-sample integration, use scVI-tools (scvi.model.SCVI), Harmony (sc.external.pp.harmony_integrate), or BBKNN (sc.external.pp.bbknn) -- all of which integrate with Scanpy but are separate packages. - CPU-only for extension workflows: On the platform, the core workflows (
full,qc,clustering,de) run GPU-accelerated via rapids-singlecell, but the batch-correction, annotation, and scoring extensions (Harmony, Scanorama, ComBat, CellTypist, AUCell, COSG, Hotspot, CytoTrace2, scVelo) run on CPU. Upstream open-source Scanpy is CPU-only; rapids-singlecell is the GPU-backed drop-in the platform uses. - No built-in multi-modal analysis: For combined scRNA-seq + scATAC-seq or CITE-seq, use muon (part of scverse) which extends AnnData to multi-modal data.
- Trajectory inference is basic: Scanpy's diffusion pseudotime and PAGA are useful for simple trajectories, but complex branching lineages are better handled by CellRank or scVelo.
Integration with scVI-tools
scVI-tools provides deep generative models that complement Scanpy's preprocessing:
- scVI: Variational autoencoder for dimensionality reduction, batch correction, and differential expression. Produces a latent space that replaces PCA for downstream clustering and visualization.
- scANVI: Semi-supervised variant of scVI that uses reference cell type labels for annotation transfer.
- SOLO: Doublet detection using a variational autoencoder.
- totalVI: Joint modeling of RNA and protein (CITE-seq) data.
The typical workflow is: preprocess with Scanpy (QC, filtering, normalization) then train a scVI model for batch-corrected embeddings and differential expression. The scVI latent space can be stored in adata.obsm['X_scVI'] and used directly with Scanpy's neighbor graph and clustering functions.
Integration with the platform ecosystem
- Upstream: Load data from 10X Genomics, Smart-seq2, or other platforms
- Downstream: Feed results to scVI-tools for advanced modeling, target validation pipelines for cell-type-specific target expression
Chat Usage
Example Prompts
- "Run Scanpy full pipeline on this H5AD file"
- "Cluster these single-cell data with Leiden resolution 0.5"
- "Run QC and normalize my scRNA-seq dataset, then find marker genes"
- "Compute UMAP and identify differentially expressed genes per cluster"
- "Run trajectory analysis with diffusion pseudotime on my preprocessed data"
Workflow Chaining
- Feeds into: Target validation (cell types expressing your target), scVI-tools (probabilistic modeling), differential expression analysis
- Accepts from: AnnData
.h5adfiles (uploaded, or produced upstream). Convert 10X Cell Ranger output or CSV matrices to.h5adbefore submitting — the job reads.h5adonly.
Read next
Genomics on the platform
Multi-database genomics query tools for gene information, pathway analysis, variant interpretation, and cross-database linking.
Epigenomics on the platform
Chromatin accessibility, histone modification, and DNA methylation analysis tools for epigenomic profiling.
Which tool?
Match a scientific goal to the tool that answers it.
Workflows
Guided pipelines and copy-and-adapt prompt recipes for common goals.
Was this page helpful?