Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >🤩 scanpy | 超高速完成单细胞分析!~(一)(预处理与聚类)

🤩 scanpy | 超高速完成单细胞分析!~(一)(预处理与聚类)

作者头像
生信漫卷
发布于 2025-05-04 06:27:42
发布于 2025-05-04 06:27:42
65000
代码可运行
举报
运行总次数:0
代码可运行

写在前面

假期这几天去骑了车子,风景美如画!~🚴

各位假期都去哪里玩了呀,人山人海吗?!😂

今天是pythonscanpy,还是要学起来这个了。😜

看现在的趋势,未来python可能才是未来,R再不做出改变就要被取代了。🙂‍↕️

用到的包

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import os
import scanpy as sc
import anndata as ad

import scrublet  # 直接导入 Scrublet

全局设置

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
sc.settings.set_figure_params(dpi=50, facecolor="white")

读入数据

这里我发现联网读取不了原始数据,我就进行了本地读取,原教程中好像代码有写问题,这里我做了修改,写了注释,大家可以试一试!~😘

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 定义样本信息(文件名与本地路径关联)
samples = {
    "s1d1": "s1d1_filtered_feature_bc_matrix.h5",
    "s1d3": "s1d3_filtered_feature_bc_matrix.h5",
}
adatas = {}

for sample_id, filename in samples.items():
    # 构建本地文件路径:scanpy_data/文件名
    local_path = os.path.join("scanpy_data", filename)

    # 读取 10x Genomics H5 文件
    sample_adata = sc.read_10x_h5(local_path)

    # 确保基因名唯一(解决单样本内基因名重复问题)
    sample_adata.var_names_make_unique()

    # 存储到字典
    adatas[sample_id] = sample_adata

# 合并所有样本的 AnnData 对象(移除 `keys` 参数)
adata = ad.concat(
    adatas,          # 直接传入字典,自动使用字典键作为样本标识
    label="sample",  # 在 obs 中添加样本来源列
    join="inner"     # 仅保留所有样本共有的基因(解决跨样本基因名不一致问题)
)

# 确保观测名(细胞条形码)唯一(解决跨样本细胞名重复问题)
adata.obs_names_make_unique()

# 打印各样本细胞数统计
print("各样本细胞数量统计:")
print(adata.obs["sample"].value_counts())

# 返回合并后的 AnnData 对象(可用于后续分析)
adata

基础质控

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# mitochondrial genes, "MT-" for human, "Mt-" for mouse
adata.var["mt"] = adata.var_names.str.startswith("MT-")
# ribosomal genes
adata.var["ribo"] = adata.var_names.str.startswith(("RPS", "RPL"))
# hemoglobin genes
adata.var["hb"] = adata.var_names.str.contains("^HB[^(P)]")

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
sc.pp.calculate_qc_metrics(
    adata, qc_vars=["mt", "ribo", "hb"], inplace=True, log1p=True
)

可视化质控指标!~😜

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
sc.pl.violin(
    adata,
    ["n_genes_by_counts", "total_counts", "pct_counts_mt"],
    jitter=0.4,
    multi_panel=True,
)

再来一张!~🫠

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
sc.pl.scatter(adata, "total_counts", "n_genes_by_counts", color="pct_counts_mt")

过滤细胞和基因!~🧐

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
sc.pp.filter_cells(adata, min_genes=100)
sc.pp.filter_genes(adata, min_cells=3)

Doublet去除

这里我发现代码也不太对,运行不下去了。💀

下面是我重新写的,亲测有效,有注释!~💪

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 确保 adata.obs 中存在 'predicted_doublet' 列,初始化为 False
adata.obs["predicted_doublet"] = False

for sample in adata.obs["sample"].unique():
    # 提取单个样本数据
    sample_mask = adata.obs["sample"] == sample
    adata_sample = adata[sample_mask].copy()

    # 运行 Scrublet
    scrub = scrublet.Scrublet(adata_sample.X)
    doublet_scores, predicted_doublets = scrub.scrub_doublets()

    # 确保 predicted_doublets 是布尔数组
    predicted_doublets = predicted_doublets.astype(bool)

    # 回填结果到原 adata(直接通过布尔索引操作)
    adata.obs.loc[sample_mask, "doublet_score"] = doublet_scores
    adata.obs.loc[sample_mask, "predicted_doublet"] = predicted_doublets

# 过滤双细胞(确保列存在且为布尔类型)
adata = adata[~adata.obs["predicted_doublet"], :].copy()

标准化

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# Saving count data
adata.layers["counts"] = adata.X.copy()
# Normalizing to median total counts
sc.pp.normalize_total(adata)
# Logarithmize the data
sc.pp.log1p(adata)

筛选特征基因

这里是top 2000!~😘

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
sc.pp.highly_variable_genes(adata, n_top_genes=2000, batch_key="sample")
sc.pl.highly_variable_genes(adata)

降维

肘图!~😘

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
sc.tl.pca(adata)
sc.pl.pca_variance_ratio(adata, n_pcs=50, log=True)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
sc.pl.pca(
    adata,
    color=["sample", "sample", "pct_counts_mt", "pct_counts_mt"],
    dimensions=[(0, 1), (2, 3), (0, 1), (2, 3)],
    ncols=2,
    size=2,
)

UMAP可视化

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
sc.pp.neighbors(adata)
sc.tl.umap(adata)
sc.pl.umap(
    adata,
    color="sample",
    # Setting a smaller point size to get prevent overlap
    size=2,
)

聚类

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# Leiden 聚类(修正参数)
sc.tl.leiden(adata, resolution=0.5)

# UMAP 计算与可视化
sc.pp.neighbors(adata, n_neighbors=15, n_pcs=50)
sc.tl.umap(adata)
sc.pl.umap(adata, color=["leiden"])

再次质控并过滤

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
sc.pl.umap(
    adata,
    color=["leiden", "predicted_doublet", "doublet_score"],
    # increase horizontal space between panels
    wspace=0.5,
    size=3,
)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
sc.pl.umap(
    adata,
    color=["leiden", "log1p_total_counts", "pct_counts_mt", "log1p_n_genes_by_counts"],
    wspace=0.5,
    ncols=2,
)

手动注释细胞类型

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from leidenalg import RBConfigurationVertexPartition

# 运行不同分辨率的 Leiden 聚类
for res in [0.02, 0.5, 2.0]:
    sc.tl.leiden(
        adata,
        key_added=f"leiden_res_{res:.2f}",
        resolution=res,
        partition_type=RBConfigurationVertexPartition
    )


代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
sc.pl.umap(
    adata,
    color=["leiden_res_0.02", "leiden_res_0.50", "leiden_res_2.00"],
    legend_loc="on data",
)

展示Marker gene

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
marker_genes = {
    "CD14+ Mono": ["FCN1", "CD14"],
    "CD16+ Mono": ["TCF7L2", "FCGR3A", "LYN"],
    # Note: DMXL2 should be negative
    "cDC2": ["CST3", "COTL1", "LYZ", "DMXL2", "CLEC10A", "FCER1A"],
    "Erythroblast": ["MKI67", "HBA1", "HBB"],
    # Note HBM and GYPA are negative markers
    "Proerythroblast": ["CDK6", "SYNGR1", "HBM", "GYPA"],
    "NK": ["GNLY", "NKG7", "CD247", "FCER1G", "TYROBP", "KLRG1", "FCGR3A"],
    "ILC": ["ID2", "PLCG2", "GNLY", "SYNE1"],
    "Naive CD20+ B": ["MS4A1", "IL4R", "IGHD", "FCRL1", "IGHM"],
    # Note IGHD and IGHM are negative markers
    "B cells": [
        "MS4A1",
        "ITGB1",
        "COL4A4",
        "PRDM1",
        "IRF4",
        "PAX5",
        "BCL11A",
        "BLK",
        "IGHD",
        "IGHM",
    ],
    "Plasma cells": ["MZB1", "HSP90B1", "FNDC3B", "PRDM1", "IGKC", "JCHAIN"],
    # Note PAX5 is a negative marker
    "Plasmablast": ["XBP1", "PRDM1", "PAX5"],
    "CD4+ T": ["CD4", "IL7R", "TRBC2"],
    "CD8+ T": ["CD8A", "CD8B", "GZMK", "GZMA", "CCL5", "GZMB", "GZMH", "GZMA"],
    "T naive": ["LEF1", "CCR7", "TCF7"],
    "pDC": ["GZMB", "IL3RA", "COBLL1", "TCF4"],
}

sc.pl.dotplot(adata, marker_genes, groupby="leiden_res_0.02", standard_scale="var")

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
adata.obs["cell_type_lvl1"] = adata.obs["leiden_res_0.02"].map(
    {
        "0": "Lymphocytes",
        "1": "Monocytes",
        "2": "Erythroid",
        "3": "B Cells",
    }
)

sc.pl.dotplot(adata, marker_genes, groupby="leiden_res_0.50", standard_scale="var")

差异表达基因作为Marker gene

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# Obtain cluster-specific differentially expressed genes
sc.tl.rank_genes_groups(adata, groupby="leiden_res_0.50", method="wilcoxon")
sc.pl.rank_genes_groups_dotplot(
    adata, groupby="leiden_res_0.50", standard_scale="var", n_genes=5
)

看一下Cluster 7的高表达基因,应该是个NK细胞。🙊

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
sc.get.rank_genes_groups_df(adata, group="7").head(5)

可视化一下Cluster 7的高表达基因。🧬

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
dc_cluster_genes = sc.get.rank_genes_groups_df(adata, group="7").head(5)["names"]
sc.pl.umap(
    adata,
    color=[*dc_cluster_genes, "leiden_res_0.50"],
    legend_loc="on data",
    frameon=False,
    ncols=3,
)

最后祝大家早日不卷!~

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-05-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 生信漫卷 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Scanpy分析全流程(含harmonypy整合/细胞周期矫正/双细胞检测及去除)
本次走一遍Scanpy全流程,数据集仍为GSE188711,该数据集可至GEO官网下载。
凑齐六个字吧
2025/06/01
2030
Scanpy分析全流程(含harmonypy整合/细胞周期矫正/双细胞检测及去除)
Scanpy 分析 scRNA-seq:细胞类型注释
本系列讲解 使用Scanpy分析单细胞(scRNA-seq)数据教程[1],持续更新,欢迎关注,转发!
数据科学工厂
2025/05/21
890
Scanpy 分析 scRNA-seq:细胞类型注释
Scanpy进行单细胞分析及发育轨迹推断
最近看文献,发现越来越多的单细胞测序使用scanpy进行轨迹推断,可能因为scanpy可以在整体umap或者Tsne基础上绘制细胞发育路径,图片也更加美观,但是Scanpy是基于python开发的,下面整理下Scanpy官网给出的流程,按照官网流程跑一遍PBMC的数据。
生信技能树jimmy
2020/12/24
4.2K0
单细胞Scanpy流程学习和整理(分析簇间差异基因/细胞注释/数据保存)
上一篇推文介绍了Scanpy流程中的10X数据读取/过滤/降维/聚类步骤,这次笔者将学习一下差异分析/细胞注释/数据保存。
凑齐六个字吧
2024/09/26
1.1K0
单细胞Scanpy流程学习和整理(分析簇间差异基因/细胞注释/数据保存)
单细胞分析的 Python 包 Scanpy(图文详解)
线粒体基因的转录本比单个转录物分子大,并且不太可能通过细胞膜逃逸。因此,检测出高比例的线粒体基因,表明细胞质量差(Islam et al. 2014; Ilicic et al. 2016)。
白墨石
2021/07/16
5.3K1
单细胞分析的 Python 包 Scanpy(图文详解)
python 单细胞scanpy流程
这篇推文耗时甚久,主要是学习和跑通官网代码,其次是加了一些自己的细微调整,比如整理marker基因表格,还有可视化的调整等。
用户11414625
2024/12/20
4840
python 单细胞scanpy流程
Scanpy 分析 scRNA-seq数据|质控
在本文中,使用的数据来源于健康人类供体的骨髓单核细胞,这些数据属于 openproblem 的 NeurIPS 2021 基准数据集。这些样本是通过 10X Multiome 基因表达和染色质可及性试剂盒进行测量的。
数据科学工厂
2025/05/14
710
Scanpy 分析 scRNA-seq数据|质控
基于python的scanpy模块的乳腺癌单细胞数据分析
这次我们来复现一篇单细胞的文章。这篇我们只来复现细胞图谱和拟时序分析 像细胞通讯,还有富集分析还是很简单的。大家可以继续走下去,然后我们来交流讨论! 这篇全篇基于python复现。
生信技能树
2021/10/12
4K1
scanpy分析单细胞数据
scanpy和seurat是最常用的分析的单细胞的工具,seurat基于R,而scanpy基于python。 linux下用pip安装scanpy
生信编程日常
2020/12/21
2.2K0
scanpy分析单细胞数据
scanpy和Seurat单细胞分析对比
尝试把曾老师的单细胞seurat分析的代码转换成scanpy版本的,包括样品读取,质控,harmony去除批次效应,降维聚类,marker鉴定。
生信技能树
2023/11/16
1.9K0
scanpy和Seurat单细胞分析对比
Python 单细胞分析教程(一):质量控制
目前,国内对于单细胞测序分析的教程五花八门,百花齐放,一个合适且准确的pipeline对于分析是很有价值的。2023年在 Nat Rev Genet上发表的一篇论文“Best practices for single-cell analysis across modalities”,详细介绍了单细胞最佳实践的流程。但是,其在国内的推广有两个不足:(一)全英文教程;(二)R语言与Python混合。二者限制了其在国内的推广,故笔者在原教程的基础上,结合自身的单细胞测序分析经验。将其译至中文版,并且只使用Python完成所有分析。环境参考此前安装的omicverse环境。
生信技能树jimmy
2023/08/31
2.3K0
Python 单细胞分析教程(一):质量控制
Visium HD 空间转录组分析探索之--基础分析
上节我们完成了Space Ranger分析,在输出结果binned_outputs文件夹内默认生成了2um, 8um, 16um bin的结果,这节我们使用10x文章中推荐的8x8um bin结果进行后续分析。为了演示,我们取P1_CRC样本数据进行后续分析(多样本合并一般都需要进行去批次处理,如果有需要,后续我们会继续分享多样本合并分析步骤)。
生信大杂烩
2025/05/29
1420
Visium HD 空间转录组分析探索之--基础分析
Scanpy 分析 scRNA-seq:降维与聚类
本系列讲解 使用Scanpy分析单细胞(scRNA-seq)数据教程[1],持续更新,欢迎关注,转发!
数据科学工厂
2025/05/18
1180
Scanpy 分析 scRNA-seq:降维与聚类
做单细胞和空转必须了解的AnnData数据结构
图解如下:https://anndata.readthedocs.io/en/stable/index.html
生信技能树
2025/04/09
3210
做单细胞和空转必须了解的AnnData数据结构
scanpy读取空转Visum HD数据&基础分析
上一期我们学习了使用python读取单细胞和空转数据(10X visum低分辨率):
生信技能树
2025/03/06
5430
scanpy读取空转Visum HD数据&基础分析
python版的singler单细胞注释工具
网上可以搜到大量的R语言singleR的代码和教程,但python版的就比较少啦,恭喜你找到了我。
用户11414625
2024/12/20
1550
python版的singler单细胞注释工具
单细胞Scanpy流程学习和整理(单样本10X数据读取/过滤/降维/聚类)
新手上路写的很繁琐,多多包涵,本次用的IDE是Visual studio code。
凑齐六个字吧
2024/09/25
1.3K0
单细胞Scanpy流程学习和整理(单样本10X数据读取/过滤/降维/聚类)
单细胞空间转录组分析流程学习python版(三)
单细胞空间转录组分析流程学习(一):https://mp.weixin.qq.com/s/E4WuPokBOxKRbBF6CEB5aA
凑齐六个字吧
2024/10/19
2460
单细胞空间转录组分析流程学习python版(三)
python单细胞学习笔记-day9(发在Science的celltypist软件注释)
在之前的conda环境中安装新的本次上课需要的几个包:(建议先不要全都安装上,很容易后面出现包导入失败,可以运行到哪个代码缺少模块再开始安装~)
生信技能树
2025/03/28
1780
python单细胞学习笔记-day9(发在Science的celltypist软件注释)
scanpy教程:预处理与聚类
scanpy 是一个用于分析单细胞转录组(single cell rna sequencing)数据的python库,文章2018发表在Genome Biology(https://genomebiology.biomedcentral.com/)。其实它的许多分析思路借鉴了以seurat为中心的R语言单细胞转录数据分析生态的,scanpy以一己之力在python生态构建了单细胞转录组数据分析框架。我相信借助python的工业应用实力,其扩展性大于R语言分析工具。当然,选择走一遍scanpy的原因,不是因为它的强大,只是因为喜欢。
生信技能树jimmy
2020/04/08
15.2K2
scanpy教程:预处理与聚类
推荐阅读
相关推荐
Scanpy分析全流程(含harmonypy整合/细胞周期矫正/双细胞检测及去除)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验