Skill Tracer
Skills › Scientific Agent Skills › scanpy › api_reference.md

api_reference.md

279 lines · skills/scanpy/references/api_reference.md at 5f2bc03

Open on GitHub
1# Scanpy API Quick Reference
2
3Reviewed for Scanpy 1.12.4 / AnnData 0.13.4 on 2026-10-01. These snippets are
4illustrative and require the named genes, groups and prior results to exist.
5Use the tested CLI workflow for a runnable starting point. Counts, normalized
6expression and `.raw` have distinct roles; see [upstream-review.md](upstream-review.md).
7
8
9Quick reference for commonly used scanpy functions organized by module.

Scanpy API Quick Reference

Reviewed for Scanpy 1.12.4 / AnnData 0.13.4 on 2026-10-01. These snippets are illustrative and require the named genes, groups and prior results to exist. Use the tested CLI workflow for a runnable starting point. Counts, normalized expression and .raw have distinct roles; see upstream-review.md.

Quick reference for commonly used scanpy functions organized by module.

Raw lines 1 to 10
11## Import Convention
13```python
14import scanpy as sc
15```

Import Convention

import scanpy as sc
Raw lines 11 to 16
17## Reading and Writing Data (sc.read_*)

Reading and Writing Data (sc.read_*)

Raw lines 17 to 18
19### Reading Functions
21```python
22sc.read_10x_h5(filename) # Read 10X HDF5 file
23sc.read_10x_mtx(path) # Read 10X mtx directory
24sc.read_h5ad(filename) # Read h5ad (AnnData) file
25sc.read_csv(filename) # Read CSV file
26sc.read_excel(filename, sheet=0) # Requires a sheet and Excel reader dependency
27sc.read_loom(filename) # Read loom file
28sc.read_text(filename) # Read text file
29sc.read_visium(path) # Deprecated; use spatialdata-io for new workflows
30```

Reading Functions

sc.read_10x_h5(filename)                    # Read 10X HDF5 file
sc.read_10x_mtx(path)                       # Read 10X mtx directory
sc.read_h5ad(filename)                      # Read h5ad (AnnData) file
sc.read_csv(filename)                       # Read CSV file
sc.read_excel(filename, sheet=0)            # Requires a sheet and Excel reader dependency
sc.read_loom(filename)                      # Read loom file
sc.read_text(filename)                      # Read text file
sc.read_visium(path)                        # Deprecated; use spatialdata-io for new workflows
Raw lines 19 to 31
32### Writing Functions
34```python
35adata.write_h5ad(filename) # Write to h5ad format
36adata.write_csvs(dirname) # Write to CSV files
37adata.write_loom(filename) # Write to loom format
38adata.write_zarr(filename) # Write to zarr format
39```

Writing Functions

adata.write_h5ad(filename)                  # Write to h5ad format
adata.write_csvs(dirname)                   # Write to CSV files
adata.write_loom(filename)                  # Write to loom format
adata.write_zarr(filename)                  # Write to zarr format
Raw lines 32 to 40
41## Preprocessing (sc.pp.*)

Preprocessing (sc.pp.*)

Raw lines 41 to 42
43### Quality Control
45```python
46sc.pp.calculate_qc_metrics(adata, qc_vars=['mt'], percent_top=None, inplace=True)
47sc.pp.filter_cells(adata, min_genes=200)
48sc.pp.filter_genes(adata, min_cells=3)
49sc.pp.scrublet(adata) # Doublet detection (core since 1.10)
50sc.pp.scrublet_simulate_doublets(adata) # Simulate doublets for benchmarking
51```

Quality Control

sc.pp.calculate_qc_metrics(adata, qc_vars=['mt'], percent_top=None, inplace=True)
sc.pp.filter_cells(adata, min_genes=200)
sc.pp.filter_genes(adata, min_cells=3)
sc.pp.scrublet(adata)                              # Doublet detection (core since 1.10)
sc.pp.scrublet_simulate_doublets(adata)            # Simulate doublets for benchmarking
Raw lines 43 to 52
53### Normalization and Transformation
55```python
56sc.pp.normalize_total(adata, target_sum=1e4) # Normalize to target sum
57sc.pp.log1p(adata) # Log(x + 1) transformation
58sc.pp.sqrt(adata) # Square root transformation
59```

Normalization and Transformation

sc.pp.normalize_total(adata, target_sum=1e4)    # Normalize to target sum
sc.pp.log1p(adata)                               # Log(x + 1) transformation
sc.pp.sqrt(adata)                                # Square root transformation
Raw lines 53 to 60
61### Feature Selection
63```python
64sc.pp.highly_variable_genes(adata, min_mean=0.0125, max_mean=3, min_disp=0.5)
65sc.pp.highly_variable_genes(adata, flavor='seurat_v3', n_top_genes=2000)
66# Dask support is experimental; v3 flavors gained support in 1.12.
67```

Feature Selection

sc.pp.highly_variable_genes(adata, min_mean=0.0125, max_mean=3, min_disp=0.5)
sc.pp.highly_variable_genes(adata, flavor='seurat_v3', n_top_genes=2000)
# Dask support is experimental; v3 flavors gained support in 1.12.
Raw lines 61 to 68
69### Scaling and Regression
71```python
72sc.pp.scale(adata, max_value=10) # Scale to unit variance
73sc.pp.regress_out(adata, ['total_counts', 'pct_counts_mt']) # Regress out unwanted variation
74```

Scaling and Regression

sc.pp.scale(adata, max_value=10)                      # Scale to unit variance
sc.pp.regress_out(adata, ['total_counts', 'pct_counts_mt'])  # Regress out unwanted variation
Raw lines 69 to 75
76### Dimensionality Reduction (Preprocessing)
78```python
79sc.pp.pca(adata, n_comps=50) # Principal component analysis
80sc.pp.neighbors(adata, n_neighbors=10, n_pcs=40) # Compute neighborhood graph
81sc.pp.neighbors(adata, method='jaccard') # Jaccard connectivities (scanpy 1.12)
82```

Dimensionality Reduction (Preprocessing)

sc.pp.pca(adata, n_comps=50)                     # Principal component analysis
sc.pp.neighbors(adata, n_neighbors=10, n_pcs=40) # Compute neighborhood graph
sc.pp.neighbors(adata, method='jaccard')         # Jaccard connectivities (scanpy 1.12)
Raw lines 76 to 83
84### Batch Correction
86```python
87sc.pp.combat(adata, key='batch') # ComBat batch correction
88```

Batch Correction

sc.pp.combat(adata, key='batch')                 # ComBat batch correction
Raw lines 84 to 89
90## Tools (sc.tl.*)

Tools (sc.tl.*)

Raw lines 90 to 91
92### Dimensionality Reduction
94```python
95sc.tl.pca(adata, svd_solver='arpack') # PCA
96sc.tl.umap(adata) # UMAP embedding
97sc.tl.tsne(adata) # t-SNE embedding
98sc.tl.diffmap(adata) # Diffusion map
99sc.tl.draw_graph(adata, layout='fa') # Force-directed graph
100```

Dimensionality Reduction

sc.tl.pca(adata, svd_solver='arpack')            # PCA
sc.tl.umap(adata)                                 # UMAP embedding
sc.tl.tsne(adata)                                 # t-SNE embedding
sc.tl.diffmap(adata)                              # Diffusion map
sc.tl.draw_graph(adata, layout='fa')             # Force-directed graph
Raw lines 92 to 101
102### Clustering
104```python
105sc.tl.leiden(adata, resolution=0.5) # Leiden clustering (recommended)
106# sc.tl.louvain(adata, resolution=0.5) # Deprecated in scanpy 1.12 — use leiden
107# K-means is not a scanpy.tl function; use sklearn.cluster.KMeans explicitly.
108```

Clustering

sc.tl.leiden(adata, resolution=0.5)              # Leiden clustering (recommended)
# sc.tl.louvain(adata, resolution=0.5)           # Deprecated in scanpy 1.12 — use leiden
# K-means is not a scanpy.tl function; use sklearn.cluster.KMeans explicitly.
Raw lines 102 to 109
110### Marker Genes and Differential Expression
112```python
113sc.tl.rank_genes_groups(adata, groupby='leiden', method='wilcoxon')
114sc.tl.rank_genes_groups(adata, groupby='leiden', method='t-test')
115sc.tl.rank_genes_groups(adata, groupby='leiden', method='logreg')
117# Get results as dataframe
118sc.get.rank_genes_groups_df(adata, group='0')
119# Exploratory only — per-cell tests inflate significance (often making p-values too small); pseudobulk for rigorous DE
120```

Marker Genes and Differential Expression

sc.tl.rank_genes_groups(adata, groupby='leiden', method='wilcoxon')
sc.tl.rank_genes_groups(adata, groupby='leiden', method='t-test')
sc.tl.rank_genes_groups(adata, groupby='leiden', method='logreg')

# Get results as dataframe
sc.get.rank_genes_groups_df(adata, group='0')
# Exploratory only — per-cell tests inflate significance (often making p-values too small); pseudobulk for rigorous DE
Raw lines 110 to 121
122### Aggregation (Pseudobulk)
124```python
125sc.get.aggregate(adata, by='cell_type', func='sum', layer='counts')
126pb = sc.get.aggregate(adata, by=['sample', 'cell_type'], func='sum', layer='counts')
127counts = pb.layers['sum'] # cells/groups x genes; pb.X is None
128# Keep biological replicate metadata; PyDESeq2 expects sample rows and gene columns.
129```

Aggregation (Pseudobulk)

sc.get.aggregate(adata, by='cell_type', func='sum', layer='counts')
pb = sc.get.aggregate(adata, by=['sample', 'cell_type'], func='sum', layer='counts')
counts = pb.layers['sum']  # cells/groups x genes; pb.X is None
# Keep biological replicate metadata; PyDESeq2 expects sample rows and gene columns.
Raw lines 122 to 130
131### Trajectory Inference
133```python
134sc.tl.paga(adata, groups='leiden') # PAGA trajectory
135sc.tl.diffmap(adata, n_comps=10) # choose fewer for small datasets
136sc.tl.dpt(adata, n_dcs=10) # Diffusion pseudotime
137```

Trajectory Inference

sc.tl.paga(adata, groups='leiden')               # PAGA trajectory
sc.tl.diffmap(adata, n_comps=10)  # choose fewer for small datasets
sc.tl.dpt(adata, n_dcs=10)                                  # Diffusion pseudotime
Raw lines 131 to 138
139### Gene Scoring
141```python
142sc.tl.score_genes(adata, gene_list, score_name='score')
143sc.tl.score_genes_cell_cycle(adata, s_genes=s_genes, g2m_genes=g2m_genes)
144```

Gene Scoring

sc.tl.score_genes(adata, gene_list, score_name='score')
sc.tl.score_genes_cell_cycle(adata, s_genes=s_genes, g2m_genes=g2m_genes)
Raw lines 139 to 145
146### Embeddings and Projections
148```python
149sc.tl.ingest(adata, adata_ref) # Map to reference
150sc.tl.embedding_density(adata, basis='umap', groupby='leiden')
151```

Embeddings and Projections

sc.tl.ingest(adata, adata_ref)                   # Map to reference
sc.tl.embedding_density(adata, basis='umap', groupby='leiden')
Raw lines 146 to 152
153## Plotting (sc.pl.*)

Plotting (sc.pl.*)

Raw lines 153 to 154
155### Basic Embeddings
157```python
158sc.pl.umap(adata, color='leiden') # UMAP plot
159sc.pl.tsne(adata, color='gene_name') # t-SNE plot
160sc.pl.pca(adata, color='leiden') # PCA plot
161sc.pl.diffmap(adata, color='leiden') # Diffusion map plot
162```

Basic Embeddings

sc.pl.umap(adata, color='leiden')                # UMAP plot
sc.pl.tsne(adata, color='gene_name')             # t-SNE plot
sc.pl.pca(adata, color='leiden')                 # PCA plot
sc.pl.diffmap(adata, color='leiden')             # Diffusion map plot
Raw lines 155 to 163
164### Heatmaps and Dot Plots
166```python
167sc.pl.heatmap(adata, var_names=genes, groupby='leiden')
168sc.pl.dotplot(adata, var_names=genes, groupby='leiden')
169sc.pl.matrixplot(adata, var_names=genes, groupby='leiden')
170sc.pl.stacked_violin(adata, var_names=genes, groupby='leiden')
171```

Heatmaps and Dot Plots

sc.pl.heatmap(adata, var_names=genes, groupby='leiden')
sc.pl.dotplot(adata, var_names=genes, groupby='leiden')
sc.pl.matrixplot(adata, var_names=genes, groupby='leiden')
sc.pl.stacked_violin(adata, var_names=genes, groupby='leiden')
Raw lines 164 to 172
173### Violin and Scatter Plots
175```python
176sc.pl.violin(adata, keys=['gene1', 'gene2'], groupby='leiden')
177sc.pl.scatter(adata, x='gene1', y='gene2', color='leiden')
178```

Violin and Scatter Plots

sc.pl.violin(adata, keys=['gene1', 'gene2'], groupby='leiden')
sc.pl.scatter(adata, x='gene1', y='gene2', color='leiden')
Raw lines 173 to 179
180### Marker Gene Visualization
182```python
183sc.pl.rank_genes_groups(adata, n_genes=25, sharey=False)
184sc.pl.rank_genes_groups_violin(adata, groups='0')
185sc.pl.rank_genes_groups_heatmap(adata, n_genes=10)
186sc.pl.rank_genes_groups_dotplot(adata, n_genes=5)
187```

Marker Gene Visualization

sc.pl.rank_genes_groups(adata, n_genes=25, sharey=False)
sc.pl.rank_genes_groups_violin(adata, groups='0')
sc.pl.rank_genes_groups_heatmap(adata, n_genes=10)
sc.pl.rank_genes_groups_dotplot(adata, n_genes=5)
Raw lines 180 to 188
189### Trajectory Visualization
191```python
192sc.pl.paga(adata, color='leiden') # PAGA graph
193# Legacy branch-order plot requires dpt_order_indices/dpt_changepoints,
194# which default n_branchings=0 does not create. Prefer the pseudotime UMAP.
195# sc.pl.dpt_timeseries(adata) # DPT timeseries
196```

Trajectory Visualization

sc.pl.paga(adata, color='leiden')                # PAGA graph
# Legacy branch-order plot requires dpt_order_indices/dpt_changepoints,
# which default n_branchings=0 does not create. Prefer the pseudotime UMAP.
# sc.pl.dpt_timeseries(adata)                      # DPT timeseries
Raw lines 189 to 197
198### QC Plots
200```python
201sc.pl.highest_expr_genes(adata, n_top=20)
202sc.pl.violin(adata, ['n_genes_by_counts', 'total_counts', 'pct_counts_mt'])
203sc.pl.scatter(adata, x='total_counts', y='n_genes_by_counts')
204```

QC Plots

sc.pl.highest_expr_genes(adata, n_top=20)
sc.pl.violin(adata, ['n_genes_by_counts', 'total_counts', 'pct_counts_mt'])
sc.pl.scatter(adata, x='total_counts', y='n_genes_by_counts')
Raw lines 198 to 205
206### Advanced Plots
208```python
209sc.pl.dendrogram(adata, groupby='leiden')
210sc.pl.correlation_matrix(adata, groupby='leiden')
211sc.pl.tracksplot(adata, var_names=genes, groupby='leiden')
212```

Advanced Plots

sc.pl.dendrogram(adata, groupby='leiden')
sc.pl.correlation_matrix(adata, groupby='leiden')
sc.pl.tracksplot(adata, var_names=genes, groupby='leiden')
Raw lines 206 to 213
214## Common Parameters

Common Parameters

Raw lines 214 to 215
216### Color Parameters
217- `color`: Variable(s) to color by (gene name, obs column)
218- `use_raw`: Use `.raw` attribute of adata
219- `palette`: Color palette to use
220- `vmin`, `vmax`: Color scale limits

Color Parameters

  • color: Variable(s) to color by (gene name, obs column)
  • use_raw: Use .raw attribute of adata
  • palette: Color palette to use
  • vmin, vmax: Color scale limits
Raw lines 216 to 221
222### Layout Parameters
223- `basis`: Embedding basis ('umap', 'tsne', 'pca', etc.)
224- `legend_loc`: Legend location ('on data', 'right margin', etc.)
225- `size`: Point size
226- `alpha`: Point transparency

Layout Parameters

  • basis: Embedding basis ('umap', 'tsne', 'pca', etc.)
  • legend_loc: Legend location ('on data', 'right margin', etc.)
  • size: Point size
  • alpha: Point transparency
Raw lines 222 to 227
228### Saving Parameters
229- `show`: Whether to show plot
230- Prefer `sc.settings.autosave` + `sc.settings.figdir` over deprecated `save=`

Saving Parameters

  • show: Whether to show plot
  • Prefer sc.settings.autosave + sc.settings.figdir over deprecated save=
Raw lines 228 to 231
232## AnnData Structure
234```python
235adata.X # Expression matrix (cells × genes)
236adata.obs # Cell annotations (DataFrame)
237adata.var # Gene annotations (DataFrame)
238adata.uns # Unstructured annotations (dict)
239adata.obsm # Multi-dimensional cell annotations (e.g., PCA, UMAP)
240adata.varm # Multi-dimensional gene annotations
241adata.layers # Additional data layers
242adata.raw # Snapshot of X/var; not necessarily counts
244# Access
245adata.obs_names # Cell barcodes
246adata.var_names # Gene names
247adata.shape # (n_cells, n_genes)
249# Slicing
250adata[cell_indices, gene_indices]
251adata[:, adata.var_names.isin(gene_list)]
252adata[adata.obs['leiden'] == '0', :]
253```

AnnData Structure

adata.X                    # Expression matrix (cells × genes)
adata.obs                  # Cell annotations (DataFrame)
adata.var                  # Gene annotations (DataFrame)
adata.uns                  # Unstructured annotations (dict)
adata.obsm                 # Multi-dimensional cell annotations (e.g., PCA, UMAP)
adata.varm                 # Multi-dimensional gene annotations
adata.layers               # Additional data layers
adata.raw                  # Snapshot of X/var; not necessarily counts

# Access
adata.obs_names            # Cell barcodes
adata.var_names            # Gene names
adata.shape                # (n_cells, n_genes)

# Slicing
adata[cell_indices, gene_indices]
adata[:, adata.var_names.isin(gene_list)]
adata[adata.obs['leiden'] == '0', :]
Raw lines 232 to 254
255## Settings
257```python
258sc.settings.verbosity = 3 # 0=error, 1=warning, 2=info, 3=hint
259sc.set_figure_params(dpi=80, facecolor='white')
260sc.settings.autoshow = False # Don't show plots automatically
261sc.settings.autosave = True # Save figures to figdir (preferred over save=)
262sc.settings.figdir = './figures/' # Figure directory
263sc.settings.file_format_figs = 'pdf' # Output format when autosave is True
264sc.settings.cachedir = './cache/' # Cache directory
265sc.settings.n_jobs = 8 # Number of parallel jobs
266```
268Note: the `save=` parameter on individual `sc.pl.*` functions is deprecated in scanpy 1.12. Use `sc.settings.autosave` and `sc.settings.figdir` instead.

Settings

sc.settings.verbosity = 3              # 0=error, 1=warning, 2=info, 3=hint
sc.set_figure_params(dpi=80, facecolor='white')
sc.settings.autoshow = False           # Don't show plots automatically
sc.settings.autosave = True            # Save figures to figdir (preferred over save=)
sc.settings.figdir = './figures/'      # Figure directory
sc.settings.file_format_figs = 'pdf'   # Output format when autosave is True
sc.settings.cachedir = './cache/'      # Cache directory
sc.settings.n_jobs = 8                 # Number of parallel jobs

Note: the save= parameter on individual sc.pl.* functions is deprecated in scanpy 1.12. Use sc.settings.autosave and sc.settings.figdir instead.

Raw lines 255 to 269
270## Useful Utilities
272```python
273sc.logging.print_header() # Print version information
274sc.logging.print_memory_usage() # Print memory usage
275adata.copy() # Create a copy of AnnData object
276import anndata as ad
277ad.concat({'sample1': adata1, 'sample2': adata2}, label='sample', join='inner')
278# Align gene IDs first; outer joins fill absent sparse features with zero.
279```

Useful Utilities

sc.logging.print_header()            # Print version information
sc.logging.print_memory_usage()        # Print memory usage
adata.copy()                           # Create a copy of AnnData object
import anndata as ad
ad.concat({'sample1': adata1, 'sample2': adata2}, label='sample', join='inner')
# Align gene IDs first; outer joins fill absent sparse features with zero.
Raw lines 270 to 279