Scanpy 单细胞分析标准工作流:从质控到细胞注释的七步全流程实战指南
【免费下载链接】scientific-agent-skillsTurn any AI agent into an AI Scientist. The #1 Agent Skills library for science, used by 190,000+ scientists worldwide. 165 ready-to-use validated skills plus 100+ scientific databases covering biology, chemistry, medicine, and drug discovery. Compatible with Cursor, Claude Code, Codex, Pi, Antigravity, and the open Agent Skills standard.项目地址: https://gitcode.com/GitHub_Trending/cl/scientific-agent-skills
本文是 GitHub 精选项目 scientific-agent-skills 中 Scanpy 技能包的实战指南。Scanpy 是构建于 AnnData 之上的可扩展单细胞 RNA-seq 分析工具包,本技能包(
skills/scanpy)提供了一条从质量控控制、归一化、降维、聚类、marker 基因鉴定、细胞类型注释到结果保存的完整七步工作流,并配套了可以直接运行的 CLI 脚本工具链。读完本文,你将掌握 Scanpy 标准分析管线的每一步代码与关键参数,能够独立完成从原始计数矩阵到带注释的.h5ad对象的完整分析,并学会出版级绘图、轨迹推断、pseudobulk 差异表达、基因集打分与批次校正等常用进阶任务。
标准分析工作流概览
标准单细胞 RNA-seq 分析流程包含七个步骤,原文档 analysis_workflow.md 给出了每一步的完整代码。这七步分别是:
- 质量控制(QC)——识别并过滤低质量细胞与基因
- 归一化与预处理——标准化、对数变换、高变基因选择
- 降维——PCA、近邻图、UMAP / t-SNE
- 聚类——Leiden 聚类(按问题选择分辨率)
- Marker 基因鉴定——逐簇差异表达排序
- 细胞类型注释——由 marker 映射簇到细胞类型
- 保存结果——写出带注释的 AnnData 对象
该技能包强调一个核心原则:优先使用scripts/下的现成脚本而非手写 scanpy 代码。15 个脚本共享同一套_common.py辅助层(统一负责按扩展名分发的数据加载、.h5ad保存、图形配置与进度日志),彼此以.h5ad输入输出衔接,每个脚本都有--help。只有在脚本未覆盖或需要特殊定制时才手写代码——而本文档后续各小节,正是这些脚本底层 scanpy 调用的完整文档。
第一步:质量控制
质控的目标是识别并过滤低质量细胞与基因。原始文档给出的手工流程如下:
# 识别线粒体基因 adata.var['mt'] = adata.var_names.str.startswith('MT-') # 计算 QC 指标 sc.pp.calculate_qc_metrics(adata, qc_vars=['mt'], inplace=True) # 可视化 QC 指标 sc.pl.violin(adata, ['n_genes_by_counts', 'total_counts', 'pct_counts_mt'], jitter=0.4, multi_panel=True) # 过滤细胞与基因 sc.pp.filter_cells(adata, min_genes=200) sc.pp.filter_genes(adata, min_cells=3) adata = adata[adata.obs.pct_counts_mt < 5, :] # 移除高线粒体比例细胞几个关键参数的取值范围,可在 SKILL.md 的 "Key Parameters to Adjust" 一节找到权威说明:
min_genes:每个细胞的最少基因数,通常取 200–500;min_cells:每个基因的最少细胞数,通常取 3–10;pct_counts_mt:线粒体计数占比阈值,通常取 5–20%。先观察 QC 图再定阈值,不要盲目套用默认值。
双细胞检测(可选)
双细胞(doublet)检测应在归一化之前的原始计数上运行。scanpy 1.10 起sc.pp.scrublet成为核心 API(此前位于scanpy.external.pp):
sc.pp.scrublet(adata) # Core API since scanpy 1.10 (was scanpy.external.pp) adata = adata[~adata.obs['predicted_doublet'], :].copy()使用 QC 脚本实现自动化分析
该技能包在 qc_analysis.py 中实现了这一整套流程的自动化。在技能目录下运行,或传入完整路径:
python skills/scanpy/scripts/qc_analysis.py input_file.h5ad --output filtered.h5ad从源码看,qc_analysis.py相比手写流程做了三点增强,值得关注:
- 更全面的基因类别注释:
annotate_gene_classes()不仅标记线粒体基因,还同时标记核糖体基因(RPS/RPL前缀)和血红蛋白基因(HB/Hb正则),支持人类与小鼠命名(qc_analysis.py)。 - 完整的过滤参数面:除了
--min-genes、--min-cells、--mt-threshold,还支持--max-genes、--min-counts、--max-counts用于剔除极端高值细胞(可能是双细胞或大量线粒体的垂死细胞)。 - 前后对照 QC 图:在过滤前绘制
_qc_before小提琴图、线粒体比例散点图,过滤后绘制_qc_after对照图,并在日志中打印"过滤保留率"。
# 更完整的调用示例(参数均可在 --help 中查到) python skills/scanpy/scripts/qc_analysis.py raw.h5ad -o filtered.h5ad \ --min-genes 500 --max-genes 6000 --mt-threshold 10 --scrublet第二步:归一化与预处理
# 归一化到每个细胞 10,000 计数 sc.pp.normalize_total(adata, target_sum=1e4) # 对数变换 sc.pp.log1p(adata) # 保存原始计数,供后续绘图使用 adata.raw = adata # 识别高变基因 sc.pp.highly_variable_genes(adata, n_top_genes=2000) sc.pl.highly_variable_genes(adata) # 子集到高变基因 adata = adata[:, adata.var.highly_variable] # 回归掉不需要的变异来源 sc.pp.regress_out(adata, ['total_counts', 'pct_counts_mt']) # 数据标准化 sc.pp.scale(adata, max_value=10)对应脚本 preprocess.py 的实现细节说明了两点重要设计:
counts层保存:脚本在归一化前将adata.X复制到adata.layers["counts"](preprocess.py),为后续 pseudobulk 聚合与严格差异表达保留原始计数。seurat_v3变体:当--flavor seurat_v3时,高变基因选择必须在归一化之前的原始计数上进行,脚本因此调整了调用顺序(preprocess.py)。
高变基因的选择同样支持--batch-key做批次感知的 HVG 选择。脚本默认不子集到 HVG(--subset-hvg才子集),而是把完整归一化对数矩阵存入adata.raw,使后续 marker 表达图可通过use_raw=True访问全部基因。
第三步:降维
# PCA sc.tl.pca(adata, svd_solver='arpack') sc.pl.pca_variance_ratio(adata, log=True) # 查看肘部图确定主成分数 # 计算近邻图 sc.pp.neighbors(adata, n_neighbors=10, n_pcs=40) # UMAP 可视化 sc.tl.umap(adata) sc.pl.umap(adata, color='leiden') # 备选:t-SNE sc.tl.tsne(adata)参数建议:n_pcs根据方差比肘部图确定;n_neighbors通常取 10–30。
对应脚本 reduce_dimensions.py 提供了一个实用的健壮性处理:计算 PCA 分量数时自动取min(args.n_comps, adata.n_vars - 1, adata.n_obs - 1)(reduce_dimensions.py),避免在基因数或细胞数少于默认 50 时越界报错。脚本还支持--use-rep X_pca_harmony,用于在批次校正后从校正过的嵌入构建近邻图——这是与batch_correct.py衔接的关键参数。
第四步:聚类
# Leiden 聚类(推荐) sc.tl.leiden(adata, resolution=0.5) sc.pl.umap(adata, color='leiden', legend_loc='on data') # 尝试多个分辨率寻找最优粒度 for res in [0.3, 0.5, 0.8, 1.0]: sc.tl.leiden(adata, resolution=res, key_added=f'leiden_{res}')resolution(分辨率)控制聚类粒度,通常取 0.4–1.2,数值越大簇越多。应该针对研究问题选择分辨率,而不是默认值。
注意:scanpy 1.12 中sc.tl.louvain已被弃用,应使用 Leiden。脚本 cluster.py 中 Leiden 采用flavor="igraph", n_iterations=2, directed=False参数组合([cluster.py](https://link.gitcode.com/i/d8b8c0d06c40f958d9a2844503976dd2#L46-L49)),这是 scanpy 1.12 默认推荐的后端。一次运行多个分辨率时,结果写入<algorithm>_<res>键(如leiden_0.3),方便对比。
python skills/scanpy/scripts/cluster.py red.h5ad -o clu.h5ad --resolution 0.3 0.5 0.8 1.0第五步:Marker 基因鉴定
原文档在此处给出了一条重要的统计警示:
rank_genes_groups仅用于探索性的簇 marker。基于逐细胞的统计检验会因细胞并非独立观测而膨胀 p 值。对于条件或样本间的严格差异表达,应先用 pseudobulk 聚合,再使用 pydeseq2 等工具。
# 为每个簇寻找 marker 基因(探索性) sc.tl.rank_genes_groups(adata, 'leiden', method='wilcoxon') # 可视化结果 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) # 以 DataFrame 形式获取结果 markers = sc.get.rank_genes_groups_df(adata, group='0')脚本 find_markers.py 支持的检验方法包括wilcoxon(默认)、t-test、t-test_overestim_var与logreg。它会为每个簇导出独立的markers_<groupby>_<group>.csv文件和一个合并的markers_<groupby>_all.csv,同时输出排名图、点图与热图。脚本还支持--use-raw在adata.raw(归一化对数矩阵)上排序——与技能包"保存 raw 供后续绘图"的最佳实践一致。
第六步:细胞类型注释
# 定义已知细胞类型的 marker 基因 marker_genes = ['CD3D', 'CD14', 'MS4A1', 'NKG7', 'FCGR3A'] # 可视化 marker sc.pl.umap(adata, color=marker_genes, use_raw=True) sc.pl.dotplot(adata, var_names=marker_genes, groupby='leiden') # 手动注释 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) # 可视化注释结果 sc.pl.umap(adata, color='cell_type', legend_loc='on data')最佳实践要求使用多个 marker 基因交叉验证注释结果,并检查 marker 表达是否符合预期生物学。技能包提供了 annotate.py 脚本将簇映射自动化:--mapping接受 JSON({"0": "CD4 T cells", ...})或两列 CSV(cluster,cell_type)映射文件;未映射到的簇会标记为Unknown。脚本还支持--markers传入{cell_type: [genes]}的参考 marker JSON,绘制"参考 dotplot"辅助决策,再落笔注释。
仓库提供了现成的映射模板 celltype_mapping.json,可直接编辑复用。
python skills/scanpy/scripts/annotate.py clu.h5ad -o ann.h5ad --mapping celltypes.json第七步:保存结果
# 保存处理后的数据 adata.write('results/processed_data.h5ad') # 导出元数据 adata.obs.to_csv('results/cell_metadata.csv') adata.var.to_csv('results/gene_metadata.csv')技能包的_common.py中的save_anndata()会自动创建输出文件的父目录(_common.py),并在日志中打印写入对象的规模。这一行为在测试 test_scripts.py 中被显式验证——管线常在results/step3/out.h5ad这类尚未存在的目录树中写入。技能包还建议在长流程的关键节点保存中间检查点(checkpoint),避免流程中途失败后全部重跑。
常见任务
完成七步主流程后,还有五个高频进阶任务。
出版级绘图
scanpy 1.12 中sc.settings.autosave与sc.settings.figdir是首选的保存方式,逐图save=参数已弃用。
# 设置高质量默认值 sc.settings.set_figure_params(dpi=300, frameon=False, figsize=(5, 5)) sc.settings.file_format_figs = 'pdf' sc.settings.figdir = './figures/' sc.settings.autosave = True # 定制样式的 UMAP(经 autosave 保存为 figures/umap.pdf) sc.pl.umap(adata, color='cell_type', palette='Set2', legend_loc='on data', legend_fontsize=12, legend_fontoutline=2, frameon=False) # marker 基因热图 sc.pl.heatmap(adata, var_names=genes, groupby='cell_type', swap_axes=True, show_gene_labels=True) # 点图 sc.pl.dotplot(adata, var_names=genes, groupby='cell_type')综合的可视化示例参见 plotting_guide.md。技能包的 plot.py 脚本覆盖了 9 种图形类型(umap / tsne / pca / violin / dotplot / matrixplot / heatmap / tracksplot / stacked_violin),并通过--use-raw控制是否使用adata.raw的归一化对数表达。
轨迹推断
# PAGA(基于分区的图抽象) sc.tl.paga(adata, groups='leiden') sc.pl.paga(adata, color='leiden') # 扩散伪时间 adata.uns['iroot'] = np.flatnonzero(adata.obs['leiden'] == '0')[0] sc.tl.dpt(adata) sc.pl.umap(adata, color='dpt_pseudotime')Pseudobulk 与条件间差异表达
先按样本与细胞类型聚合为 pseudobulk,再做严格 DE(如 pydeseq2),而非使用逐细胞的rank_genes_groups。
# 按样本和细胞类型聚合计数(scanpy 1.12 起兼容 dask) pb = sc.get.aggregate( adata, by=['sample', 'cell_type'], func='sum', layer='counts', # 如有原始计数层则使用它 ) # 下游:导出 pb 并使用 pydeseq2 进行条件比较技能包的 pseudobulk.py 把这一过程封装为完整命令:按--by指定的多个 obs 列(如sample cell_type)聚合counts层,导出基因 × pseudobulk 样本的计数矩阵_counts.csv与样本元数据_samples.csv,直接供 pydeseq2 / edgeR / limma 使用(pseudobulk.py):
python skills/scanpy/scripts/pseudobulk.py ann.h5ad --by sample cell_type --out-prefix results/pb当需要在簇内做快速探索性比较时,rank_genes_groups可以接受,但要谨慎解读 p 值:
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 = ['CD3D', 'CD3E', 'CD3G'] sc.tl.score_genes(adata, gene_set, score_name='T_cell_score') sc.pl.umap(adata, color='T_cell_score')脚本 score_genes.py 扩展了这一能力:从 JSON 文件读取多个命名基因集逐一打分(自动过滤不在数据中的基因并给出提示),还内置了 Tirosh et al. (2016) 的人类细胞周期基因列表,可通过--cell-cycle一键计算S_score、G2M_score与phase列。基因集模板见 gene_signatures.json。
批次校正
# ComBat 批次校正 sc.pp.combat(adata, key='batch') # 备选:使用 Harmony 或 scVI(独立包)SKILL.md 建议:对于需要概率建模与深度学习的批次校正场景,改用scvi-tools技能包。技能包的 batch_correct.py 则提供了三种方法的一体化封装:
- harmony(默认推荐):在 PCA 嵌入上校正,写出
obsm['X_pca_harmony'],需uv pip install harmonypy;之后用reduce_dimensions.py --use-rep X_pca_harmony衔接; - bbknn:批次平衡的 kNN 图,替换
sc.pp.neighbors,需uv pip install bbknn,之后直接聚类; - combat:就地校正表达矩阵(
sc.pp.combat),内置于 scanpy,之后重跑降维。
python skills/scanpy/scripts/batch_correct.py red.h5ad -o int.h5ad --method harmony --batch-key sample端到端执行:一键管线与分步链
技能包提供两种执行方式,见 SKILL.md 的 Script Toolkit 一节。
一键端到端(run_pipeline.py 一次性完成 load → QC → 归一化 → HVG → PCA →(批次校正)→ UMAP → Leiden → markers):
# 计数矩阵 → 聚类、带 marker 的注释对象 + 图 + marker CSV python skills/scanpy/scripts/run_pipeline.py raw.h5ad -o processed.h5ad \ --resolution 0.5 --n-top-genes 2000 --scrublet # 多样本整合: python skills/scanpy/scripts/run_pipeline.py raw.h5ad -o processed.h5ad --batch-key sample --batch-method harmony # 通过 JSON 复现参数(键名对应带下划线的 flag 名): python skills/scanpy/scripts/run_pipeline.py raw.h5ad -o processed.h5ad --config params.json从源码看,run_pipeline.py的apply_config()会把 JSON 中的键(k.replace("-", "_"))直接写入 argparse 命名空间(run_pipeline.py)。仓库提供了可直接编辑的 pipeline_config.json 模板,包含min_genes=200、max_genes=6000、mt_threshold=10、scrublet=true、target_sum=10000、n_top_genes=2000、n_pcs=40、n_neighbors=15、resolution=0.5等一组稳妥默认值。
分步执行(需要在阶段间检查/迭代时使用):
python skills/scanpy/scripts/qc_analysis.py raw.h5ad -o qc.h5ad --scrublet python skills/scanpy/scripts/preprocess.py qc.h5ad -o norm.h5ad --n-top-genes 2000 python skills/scanpy/scripts/reduce_dimensions.py norm.h5ad -o red.h5ad --n-pcs 40 python skills/scanpy/scripts/cluster.py red.h5ad -o clu.h5ad --resolution 0.3 0.5 0.8 python skills/scanpy/scripts/find_markers.py clu.h5ad -o clu.h5ad --groupby leiden --use-raw # 检查 results/markers/*.csv,决定标签,编写映射 JSON,然后: python skills/scanpy/scripts/annotate.py clu.h5ad -o ann.h5ad --mapping celltypes.json这条分步链中的每个脚本都接受任意输入格式(.h5ad、10x 目录 /.h5、.csv、.loom、.mtx),由_common.py的load_anndata()按扩展名自动分发(_common.py),遇到未识别格式会明确报错而非猜测——这一行为同样有测试覆盖(test_scripts.py)。
关键参数速查
| 环节 | 参数 | 典型取值范围 / 默认值 |
|---|---|---|
| QC | min_genes | 200–500 |
| QC | min_cells | 3–10 |
| QC | pct_counts_mt | 5–20%(先看图再定) |
| 归一化 | target_sum | 默认 1e4 |
| 特征选择 | n_top_genes | 通常 2000–3000 |
| 特征选择 | min_mean/max_mean/min_disp | HVG 选择参数 |
| 降维 | n_pcs | 依方差比图确定 |
| 降维 | n_neighbors | 通常 10–30 |
| 聚类 | resolution | 0.4–1.2,越大簇越多 |
常见陷阱与最佳实践
综合 SKILL.md 与本文档,以下是本技能包沉淀的 11 条核心经验:
- 始终保存原始计数:在过滤基因前执行
adata.raw = adata; - 仔细检查 QC 图:基于数据集质量调整阈值,而非照抄默认值;
- 使用 Leiden 聚类:scanpy 1.12 中
sc.tl.louvain已弃用; - 尝试多个聚类分辨率:找到最优粒度;
- 验证细胞类型注释:使用多个 marker 基因交叉验证;
- 基因表达图使用
use_raw=True:显示来自.raw的归一化计数; - 检查 PCA 方差比:据此确定最优主成分数;
- 保存中间结果:长流程可能中途失败;
- DE 使用 pseudobulk:不要将
rank_genes_groups的 p 值当作条件间严格 DE 的证据; - 通过 settings 保存图:使用
sc.settings.autosave而非已弃用的逐图save=; - R 对象先转换再进 Scanpy:使用 R 工具将 Seurat / SingleCellExperiment
.rds转成.h5ad,保留计数、元数据与基因标识(转换运行手册见 r_interop.md)。
进一步阅读
- standard_workflow.md:带详细解释与完整代码的逐步工作流参考;
- api_reference.md:按模块组织的函数速查表(读写、
sc.pp.*、sc.tl.*、sc.pl.*、AnnData 操作、设置工具); - plotting_guide.md:出版级图形定制、多面板图、调色板与样式的全面指南;
- r_interop.md:macOS / Linux / Windows 上的 R 安装与格式转换运行手册;
- analysis_template.py:从数据加载到细胞类型注释的完整分析模板,复制后编辑参数即可运行。
本技能包与仓库中的anndata技能(负责 AnnData 结构与 I/O)以及scvi-tools技能(概率建模与批次校正)构成互补的 scRNA-seq 分析生态。结合 tests/scanpy/test_scripts.py 中针对_common.py共享层与各脚本 CLI 的契约测试,你可以放心地将这条七步工作流作为单细胞分析的默认起点。
【免费下载链接】scientific-agent-skillsTurn any AI agent into an AI Scientist. The #1 Agent Skills library for science, used by 190,000+ scientists worldwide. 165 ready-to-use validated skills plus 100+ scientific databases covering biology, chemistry, medicine, and drug discovery. Compatible with Cursor, Claude Code, Codex, Pi, Antigravity, and the open Agent Skills standard.项目地址: https://gitcode.com/GitHub_Trending/cl/scientific-agent-skills
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考