Scanpy 单细胞分析标准工作流:从质控到细胞注释的七步全流程实战指南
2026/9/12 19:51:09 网站建设 项目流程

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 给出了每一步的完整代码。这七步分别是:

  1. 质量控制(QC)——识别并过滤低质量细胞与基因
  2. 归一化与预处理——标准化、对数变换、高变基因选择
  3. 降维——PCA、近邻图、UMAP / t-SNE
  4. 聚类——Leiden 聚类(按问题选择分辨率)
  5. Marker 基因鉴定——逐簇差异表达排序
  6. 细胞类型注释——由 marker 映射簇到细胞类型
  7. 保存结果——写出带注释的 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相比手写流程做了三点增强,值得关注:

  1. 更全面的基因类别注释annotate_gene_classes()不仅标记线粒体基因,还同时标记核糖体基因(RPS/RPL前缀)和血红蛋白基因(HB/Hb正则),支持人类与小鼠命名(qc_analysis.py)。
  2. 完整的过滤参数面:除了--min-genes--min-cells--mt-threshold,还支持--max-genes--min-counts--max-counts用于剔除极端高值细胞(可能是双细胞或大量线粒体的垂死细胞)。
  3. 前后对照 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-testt-test_overestim_varlogreg。它会为每个簇导出独立的markers_<groupby>_<group>.csv文件和一个合并的markers_<groupby>_all.csv,同时输出排名图、点图与热图。脚本还支持--use-rawadata.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.autosavesc.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_scoreG2M_scorephase列。基因集模板见 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.pyapply_config()会把 JSON 中的键(k.replace("-", "_"))直接写入 argparse 命名空间(run_pipeline.py)。仓库提供了可直接编辑的 pipeline_config.json 模板,包含min_genes=200max_genes=6000mt_threshold=10scrublet=truetarget_sum=10000n_top_genes=2000n_pcs=40n_neighbors=15resolution=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.pyload_anndata()按扩展名自动分发(_common.py),遇到未识别格式会明确报错而非猜测——这一行为同样有测试覆盖(test_scripts.py)。

关键参数速查

环节参数典型取值范围 / 默认值
QCmin_genes200–500
QCmin_cells3–10
QCpct_counts_mt5–20%(先看图再定)
归一化target_sum默认 1e4
特征选择n_top_genes通常 2000–3000
特征选择min_mean/max_mean/min_dispHVG 选择参数
降维n_pcs依方差比图确定
降维n_neighbors通常 10–30
聚类resolution0.4–1.2,越大簇越多

常见陷阱与最佳实践

综合 SKILL.md 与本文档,以下是本技能包沉淀的 11 条核心经验:

  1. 始终保存原始计数:在过滤基因前执行adata.raw = adata
  2. 仔细检查 QC 图:基于数据集质量调整阈值,而非照抄默认值;
  3. 使用 Leiden 聚类:scanpy 1.12 中sc.tl.louvain已弃用;
  4. 尝试多个聚类分辨率:找到最优粒度;
  5. 验证细胞类型注释:使用多个 marker 基因交叉验证;
  6. 基因表达图使用use_raw=True:显示来自.raw的归一化计数;
  7. 检查 PCA 方差比:据此确定最优主成分数;
  8. 保存中间结果:长流程可能中途失败;
  9. DE 使用 pseudobulk:不要将rank_genes_groups的 p 值当作条件间严格 DE 的证据;
  10. 通过 settings 保存图:使用sc.settings.autosave而非已弃用的逐图save=
  11. 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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询