scanpy – Data & Science skill for AI agents
Scanpy is a scalable Python toolkit for analyzing single-cell RNA-seq data, built on AnnData. Apply this skill for complete single-cell workflows including quality control, normalization, dimensionality reduction, clustering, marker gene identification, visualization, and trajectory analysis.
Install the scanpy skill with one command
Pick the tool you use, copy the command and paste it in your terminal. The skill lands in that tool's skills folder and is ready in your next session.
Claude Code
mkdir -p ~/.claude/skills && curl -fsSL https://skill.dn1nguoi.com/z/scanpy-53588.tgz | tar xz -C ~/.claude/skills
Call it in Claude Code: /scanpy – then describe the task you want done.
Codex
mkdir -p ~/.codex/skills && curl -fsSL https://skill.dn1nguoi.com/z/scanpy-53588.tgz | tar xz -C ~/.codex/skills
Call it in Codex: $scanpy – then describe the task you want done.
Hermes Agent
mkdir -p ~/.hermes/skills && curl -fsSL https://skill.dn1nguoi.com/z/scanpy-53588.tgz | tar xz -C ~/.hermes/skills
Call it in Hermes Agent: /scanpy – then describe the task you want done.
DeepSeek
mkdir -p ~/.deepcode/skills && curl -fsSL https://skill.dn1nguoi.com/z/scanpy-53588.tgz | tar xz -C ~/.deepcode/skills
Call it in DeepSeek: /scanpy – then describe the task you want done.
SKILL.md content
Bundled upstream support
Supporting files are included at skill-relative paths. See [UPSTREAM-NOTICE.md](UPSTREAM-NOTICE.md) for their pinned sources, licenses, hashes, and import changes.
Scanpy: Single-Cell Analysis
Overview
Scanpy is a scalable Python toolkit for analyzing single-cell RNA-seq data, built on AnnData. Apply this skill for complete single-cell workflows including quality control, normalization, dimensionality reduction, clustering, marker gene identification, visualization, and trajectory analysis.
When to Use This Skill
This skill should be used when:
- Analyzing single-cell RNA-seq data (.h5ad, 10X, CSV formats)
- Performing quality control on scRNA-seq datasets
- Creating UMAP, t-SNE, or PCA visualizations
- Identifying cell clusters and finding marker genes
- Annotating cell types based on gene expression
- Conducting trajectory inference or pseudotime analysis
- Generating publication-quality single-cell plots
Analysis boundaries
Confirm species, gene-ID mapping, raw-count provenance and donor/sample design. QC cutoffs, regression and cluster labels are illustrative; regression can remove biology and densify sparse data. Never copy numeric cluster-to-cell-type mappings as validated annotations. Cell-level condition tests are exploratory and do not replace replicate-aware/pseudobulk inference. Keep human data local unless explicitly authorized, preserve original inputs and choose fresh output paths. The bundled support license is MIT; the entrypoint's legacy license label is unresolved and must not be treated as a verified redistribution grant.
Quick Start
Basic Import and Setup
import scanpy as sc
import pandas as pd
import numpy as np
# Configure settings
sc.settings.verbosity = 3
sc.settings.set_figure_params(dpi=80, facecolor='white')
sc.settings.figdir = './figures/'Loading Data
# From 10X Genomics
adata = sc.read_10x_mtx('path/to/data/')
adata = sc.read_10x_h5('path/to/data.h5')
# From h5ad (AnnData format)
adata = sc.read_h5ad('path/to/data.h5ad')
# From CSV
adata = sc.read_csv('path/to/data.csv')Understanding AnnData Structure
The AnnData object is the core data structure in scanpy:
adata.X # Expression matrix (cells × genes)
adata.obs # Cell metadata (DataFrame)
adata.var # Gene metadata (DataFrame)
adata.uns # Unstructured annotations (dict)
adata.obsm # Multi-dimensional cell data (PCA, UMAP)
adata.raw # Snapshot of X/var; contents depend on assignment time
# Access cell and gene names
adata.obs_names # Cell barcodes
adata.var_names # Gene namesStandard Analysis Workflow
1. Quality Control
Identify and filter low-quality cells and genes:
# Identify mitochondrial genes
adata.var['mt'] = adata.var_names.str.startswith('MT-')
# Gene symbols/species must be verified; this example uses human symbols.
adata.var['mt'] = adata.var_names.str.startswith('MT-')
# Calculate QC metrics
sc.pp.calculate_qc_metrics(adata, qc_vars=['mt'], inplace=True)
# Visualize QC metrics
sc.pl.violin(adata, ['n_genes_by_counts', 'total_counts', 'pct_counts_mt'],
jitter=0.4, multi_panel=True)
# Filter cells and genes
sc.pp.filter_cells(adata, min_genes=200)
sc.pp.filter_genes(adata, min_cells=3)
adata = adata[adata.obs.pct_counts_mt < 5, :] # Remove high MT% cellsUse the QC script for automated analysis:
python scripts/qc_analysis.py input_file.h5ad --output filtered.h5ad2. Normalization and Preprocessing
# Preserve counts before normalization (only if X contains counts)
adata.layers['counts'] = adata.X.copy()
# Normalize to 10,000 counts per cell
sc.pp.normalize_total(adata, target_sum=1e4)
# Log-transform
sc.pp.log1p(adata)
# Save log-normalized full-gene expression for later
adata.raw = adata
# Identify highly variable genes
sc.pp.highly_variable_genes(adata, n_top_genes=2000)
sc.pl.highly_variable_genes(adata)
# Subset to highly variable genes
adata = adata[:, adata.var.highly_variable]
# Regress out unwanted variation
sc.pp.regress_out(adata, ['total_counts', 'pct_counts_mt'])
# Scale data
sc.pp.scale(adata, max_value=10)3. Dimensionality Reduction
# PCA
sc.tl.pca(adata, svd_solver='arpack')
sc.pl.pca_variance_ratio(adata, log=True) # Check elbow plot
# Compute neighborhood graph
sc.pp.neighbors(adata, n_neighbors=10, n_pcs=40)
# UMAP for visualization
sc.tl.umap(adata)
# Plot by leiden only after the clustering step below.
# Alternative: t-SNE
sc.tl.tsne(adata)4. Clustering
# Leiden clustering (recommended)
sc.tl.leiden(adata, resolution=0.5)
sc.pl.umap(adata, color='leiden', legend_loc='on data')
# Try multiple resolutions to find optimal granularity
for res in [0.3, 0.5, 0.8, 1.0]:
sc.tl.leiden(adata, resolution=res, key_added=f'leiden_{res}')5. Marker Gene Identification
# Find marker genes for each cluster
sc.tl.rank_genes_groups(adata, 'leiden', method='wilcoxon')
# Visualize results
sc.pl.rank_genes_groups(adata, n_genes=25, sharey=False)
sc.pl.rank_genes_groups_heatmap(adata, n_genes=10)
sc.pl.rank_genes_groups_dotplot(adata, n_genes=5)
# Get results as DataFrame
markers = sc.get.rank_genes_groups_df(adata, group='0')6. Cell Type Annotation
# Define marker genes for known cell types
marker_genes = ['CD3D', 'CD14', 'MS4A1', 'NKG7', 'FCGR3A']
# Visualize markers
sc.pl.umap(adata, color=marker_genes, use_raw=True)
sc.pl.dotplot(adata, var_names=marker_genes, groupby='leiden')
# Manual annotation
cluster_to_celltype = {
'0': 'CD4 T cells',
'1': 'CD14+ Monocytes',
'2': 'B cells',
'3': 'CD8 T cells',
}
adata.obs['cell_type'] = adata.obs['leiden'].map(cluster_to_celltype)
# Visualize annotated types
sc.pl.umap(adata, color='cell_type', legend_loc='on data')7. Save Results
# Save processed data
adata.write('results/processed_data.h5ad')
# Export metadata
adata.obs.to_csv('results/cell_metadata.csv')
adata.var.to_csv('results/gene_metadata.csv')Common Tasks
Creating Publication-Quality Plots
# Set high-quality defaults
sc.settings.set_figure_params(dpi=300, frameon=False, figsize=(5, 5))
sc.settings.file_format_figs = 'pdf'
# UMAP with custom styling
sc.pl.umap(adata, color='cell_type',
palette='Set2',
legend_loc='on data',
legend_fontsize=12,
legend_fontoutline=2,
frameon=False,
save='_publication.pdf')
# Heatmap of marker genes
sc.pl.heatmap(adata, var_names=genes, groupby='cell_type',
swap_axes=True, show_gene_labels=True,
save='_markers.pdf')
# Dot plot
sc.pl.dotplot(adata, var_names=genes, groupby='cell_type',
save='_dotplot.pdf')Refer to references/plotting_guide.md for comprehensive visualization examples.
Trajectory Inference
# PAGA (Partition-based graph abstraction)
sc.tl.paga(adata, groups='leiden')
sc.pl.paga(adata, color='leiden')
# Diffusion pseudotime
adata.uns['iroot'] = np.flatnonzero(adata.obs['leiden'] == '0')[0]
sc.tl.diffmap(adata)
sc.tl.dpt(adata)
sc.pl.umap(adata, color='dpt_pseudotime')Differential Expression Between Conditions
# Compare treated vs control within cell types
adata_subset = adata[adata.obs['cell_type'] == 'T cells']
sc.tl.rank_genes_groups(adata_subset, groupby='condition',
groups=['treated'], reference='control')
sc.pl.rank_genes_groups(adata_subset, groups=['treated'])Gene Set Scoring
# Score cells for gene set expression
gene_set = ['CD3D', 'CD3E', 'CD3G']
sc.tl.score_genes(adata, gene_set, score_name='T_cell_score')
sc.pl.umap(adata, color='T_cell_score')Batch Correction
# ComBat batch correction
sc.pp.combat(adata, key='batch')
# Alternative: use Harmony or scVI (separate packages)Key Parameters to Adjust
Quality Control
min_genes: Minimum genes per cell (typically 200-500)min_cells: Minimum cells per gene (typically 3-10)pct_counts_mt: Mitochondrial threshold (typically 5-20%)
Normalization
target_sum: Target counts per cell (default 1e4)
Feature Selection
n_top_genes: Number of HVGs (typically 2000-3000)min_mean,max_mean,min_disp: HVG selection parameters
Dimensionality Reduction
n_pcs: Number of principal components (check variance ratio plot)n_neighbors: Number of neighbors (typically 10-30)
Clustering
resolution: Clustering granularity (0.4-1.2, higher = more clusters)
Common Pitfalls and Best Practices
1. Preserve counts: adata.layers["counts"] = adata.X.copy() before normalization; .raw here holds log-normalized expression
2. Check QC plots carefully: Adjust thresholds based on dataset quality
3. Use Leiden over Louvain: More efficient and better results
4. **Try multiple cluste
… (full content is in the download package)
Related skills
- scientific-writing – Draft and revise scientific manuscripts with evidence-based structure, citation…
- scikit-learn – Machine learning in Python with scikit-learn. Use for classification, regression…
- seaborn – Seaborn is a Python visualization library for creating publication-quality statistical…
- search-specialist – Research questions with focused web searches, primary-source verification, and explicit…
- second-deposit-igaming – Explore local casino deposit exports with heuristic signals and descriptive comparisons…
- segment-cdp – Expert patterns for Segment Customer Data Platform including Analytics.js, server-side…
- senior-fullstack – Coordinate full-stack implementation across interface, service, database and delivery…
- skill-gap-analysis – Skill gap register: employee, skill area, current against required level, gap severity…