没听错吧!单细胞中也可以进行免疫浸润分析?SpatialCells带给你新的体验!

学术   2024-10-14 19:00   上海  

前言

谈起生信分析必备项目免疫浸润分析,小伙伴们再熟悉不过了!像小伙伴们耳熟能详的ImmuCellAL、Cibersort都只能在RNA-Seq和芯片数据中使用,像目前火爆的单细胞组学数据这两个R包却无用武之地!今天大果叔带大家学习如何在单细胞数据中进行免疫浸润分析!对,你没听错,单细胞中也可以进行免疫浸润分析。SpatialCells的功能涵盖了肿瘤微环境分析的各个方面,例如基于区域的细胞组成、肿瘤增殖指数、肿瘤分离指数、免疫细胞浸润和肿瘤免疫距离等。SpatialCells的功能实在太强大了,今天果叔着重带大家学习单细胞中的免疫浸润分析!此外,SpatialCells 也有助于后续的关联分析和机器学习预测,使其成为推进我们对肿瘤生长、侵袭和转移理解的重要工具。生信分析不熟悉的小伙伴们欢迎来滴滴果叔,果叔就是这么的宠粉,有什么生信分析上的问题大家尽管咨询果叔!没有时间学习的小伙伴们也不要着急哦!有需要生信分析的小伙伴们也可以找果叔哦!练了十年生信分析的果叔对于生信分析知识已经如鱼得水从分析到可视化直到你满意为止!
生信数据处理起来占用内存实在太大了,放过自己的电脑吧!果叔在这里给大家送上福利了,有需要服务器的小伙伴们,欢迎大家联系果叔,保证服务器的性价比最高哦!


线上课程教学

课题设计、定制生信分析

云服务器租赁

加微信备注99领取使用 

代码教程
SpatialCells 目前只能从源安装。要安装,请从存储库下载代码并切换到代码文件夹。
从 SpatialCells 的根目录运行以下命令:
pip install -r requirements.txtpip install .
建议在虚拟环境中安装 SpatialCells,例如 conda。可以使用以下 yaml 文件创建 conda 环境:
conda env create --name spatialcells --file=conda.yamlpip install .conda.yaml 指定如下:name: spatial-cells-env               channels:  - conda-forge  - defaultsdependencies:  - python>=3.7, <3.11  - ipykernel  - matplotlib>=3.7.0  - pandas>=2.0.3  - seaborn>=0.12.2  - shapely>=2.0  - tqdm  - pip  - pip:      - anndata==0.9.2      - scanpy==1.9.4           加载相关的python包import pandas as pdimport matplotlib.pyplot as pltimport anndata as adimport spatialcells as spc             
在本节中,我们以免疫细胞浸润分析为导向的分析的结果来展示 SpatialCells 的功能。我们的分析涉及由1110585个细胞组成的皮肤黑色素瘤样本(MEL1)的公开多路复用成数据。
读取和预处理数据
adata = ad.read_h5ad("../../data/MEL1_adata.h5ad")spc.prep.setGate(adata, "KERATIN_cellRingMask", 6.4, debug=True)spc.prep.setGate(adata, "SOX10_cellRingMask", 7.9, debug=True)spc.prep.setGate(adata, "CD3D_cellRingMask", 7, debug=True)
         

 

肿瘤边缘暴露于来自基质区域的细胞浸润、物理接触和可扩散趋化梯度,反之亦然。因此,定义肿瘤和基质边界使我们能够更具体地评估侵袭性黑色素瘤肿瘤细胞与微环境之间的复杂相互作用,并识别新的标记物。
分离肿瘤细胞群落并绘制区域边界
marker = ["SOX10_cellRingMask_positive"]communitycolumn = "COI_community"ret = spc.spatial.getCommunities(adata, marker, eps=60, newcolumn=communitycolumn)fig, ax = plt.subplots(figsize=(10, 8))spc.plt.plotCommunities(    adata, ret, communitycolumn, plot_first_n_clusters=10, s=2, fontsize=10, ax=ax)    ax.invert_yaxis()plt.show()
         

 

绘制肿瘤的区域边界
communityIndexList = [6, 3, 14, 51, 29, 47, 39, 44, 22]boundary = spc.spatial.getBoundary(    adata, communitycolumn, communityIndexList, alpha=130)boundary = spc.spa.pruneSmallComponents(boundary, min_edges=50, holes_min_edges=500)roi_boundary = spc.spa.getExtendedBoundary(boundary, offset=2000)markersize = 1    fig, ax = plt.subplots(figsize=(10, 7))## all pointsax.scatter(    *zip(*adata.obs[["X_centroid", "Y_centroid"]].to_numpy()),    s=markersize,    color="grey",    alpha=0.2)# Points in selected commnitiesxy = adata.obs[adata.obs[communitycolumn].isin(communityIndexList)][    ["X_centroid", "Y_centroid"]].to_numpy()ax.scatter(xy[:, 0], xy[:, 1], s=markersize, color="r")# Bounds of points in selected commnitiesspc.plt.plotBoundary(boundary, ax=ax, label="Boundary", color="b")spc.plt.plotBoundary(roi_boundary, ax=ax, label="ROI boundary", color="g")ax.invert_yaxis()plt.show() 
   
将细胞分配到肿瘤区域
spc.spatial.assignPointsToRegions(    adata,    [boundary, roi_boundary],    ["Tumor", "Tumor_ROI"],    assigncolumn="region",    default="BG",)point_size = 1fig, ax = plt.subplots(figsize=(10, 7))for region in sorted(set(adata.obs["region"])):        tmp = adata.obs[adata.obs.region == region]    ax.scatter(        *zip(*tmp[["X_centroid", "Y_centroid"]].to_numpy()),        s=point_size,        alpha=0.7,        label=region    )# Bounds of points in selected commnitiesspc.plt.plotBoundary(boundary, ax=ax, label="Boundary", color="purple")spc.plt.plotBoundary(roi_boundary, ax=ax, label="ROI boundary", color="r")plt.legend(loc="upper right")ax.invert_yaxis()plt.show()
 

 

根据现有表型概括细胞类型
def merge_pheno(row):    if row["phenotype_large_cohort"] in [        "T cells",        "Cytotoxic T cells",        "Exhausted T cells",    ]:        return "T cells"    elif row["phenotype_large_cohort"] in ["Melanocytes"]:        return "Tumor cells"    else:        return "Other cells"def cell_type(row):    if row["SOX10_cellRingMask_positive"]:        return "SOX10+"    elif row["CD3D_cellRingMask_positive"]:        return "CD3D+"    else:        return "Other cells"# Applying the function to create the new columnsadata.obs["pheno1"] = pd.Categorical(adata.obs.apply(merge_pheno, axis=1))    adata.obs["Cell Types"] = pd.Categorical(adata.obs.apply(cell_type, axis=1))spc.msmt.getRegionComposition(adata, "pheno1")
         

 

在肿瘤ROI区域找到免疫细胞浸润区域
melano = adata[    (adata.obs.SOX10_cellRingMask_positive) & (adata.obs.region.isin(["Tumor_ROI", "Tumor"]))]tcells = adata[    (adata.obs.CD3D_cellRingMask_positive)    & (adata.obs.region.isin(["Tumor_ROI", "Tumor"]))]           fig, ax = plt.subplots(figsize=(10, 7))ax.invert_yaxis()ax.set_aspect("equal")plt.scatter(    tcells.obs["X_centroid"],    tcells.obs["Y_centroid"],    s=0.5,    label="T cells",        color="green",    alpha=0.5,)spc.plt.plotBoundary(roi_boundary, ax=ax, label="ROI boundary", color="r")           plt.legend(loc="upper right", markerscale=5)plt.show()
tumor = adata[adata.obs.region.isin(["Tumor_ROI", "Tumor"])]communitycolumn = "CD3D_cellRingMask_positive"communityIndexList = [True]           immune_boundary = spc.spatial.getBoundary(    tumor, communitycolumn, communityIndexList, alpha=130    )immune_boundary = spc.spa.pruneSmallComponents(    immune_boundary, min_edges=25, holes_min_edges=30, min_area=30000)markersize = 0.1fig, ax = plt.subplots(figsize=(10, 7))           ## all pointsax.scatter(    *zip(*adata.obs[["X_centroid", "Y_centroid"]].to_numpy()),    s=markersize,    color="grey",    alpha=0.2)           # Points in selected commnitiesxy = tumor.obs[tumor.obs[communitycolumn].isin(communityIndexList)][    ["X_centroid", "Y_centroid"]].to_numpy()ax.scatter(xy[:, 0], xy[:, 1], s=markersize, color="green", alpha=1, label="T cells")               # Bounds of points in selected commnitiesspc.plt.plotBoundary(    immune_boundary, ax=ax, label="Immune Cell Region Boundary", color="k", linewidth=1)           spc.plt.plotBoundary(roi_boundary, ax=ax, label="ROI boundary", color="r")# ax.set_xlim(0, 20000)# ax.set_ylim(0, 13000)ax.invert_yaxis()ax.set_aspect("equal")ax.set_axis_off()# plt.legend(loc="upper right", markerscale=5, fontsize=13.5)# plt.savefig("immune_cell_region1.png", dpi=400)plt.show() 
   
spc.spatial.assignPointsToRegions(    melano, [immune_boundary], ["T"], assigncolumn="tumor_isolated_region", default="F")
         

 

我们可以通过将已识别的免疫浸润区域与所有肿瘤细胞重叠来估计免疫浸润的规模。
point_size = 0.5fig, ax = plt.subplots(figsize=(10, 7))ax.scatter(    *zip(*adata.obs[["X_centroid", "Y_centroid"]].to_numpy()),    s=markersize,    color="grey",        alpha=0.2)           colors = ["red", "orange"]labels = ["Immune-isolated Tumor Cells", "Immune-rich Tumor Cells"]for i, region in enumerate(sorted(set(melano.obs["tumor_isolated_region"]))):    tmp = melano.obs[melano.obs.tumor_isolated_region == region]    ax.scatter(        *zip(*tmp[["X_centroid", "Y_centroid"]].to_numpy()),        s=point_size,        alpha=0.5,        color=colors[i],        label=labels[i]    )           # Bounds of points in selected commnitiesspc.plt.plotBoundary(    immune_boundary, ax=ax, label="Immune Cell Region Boundary", color="k", linewidth=1)spc.plt.plotBoundary(roi_boundary, ax=ax, label="ROI boundary", color="b")    ax.invert_yaxis()ax.set_axis_off()# plt.savefig("roi_region1.png", dpi=400)plt.show()
print("Percentage of tumor cells in immune-isolated regions: ")melano.obs["tumor_isolated_region"].value_counts() / len(melano.obs)
         

 

我们还可以通过比较肿瘤区域和免疫细胞区域之间的区域重叠来观察免疫浸润的规模。
roi_area = spc.msmt.getRegionArea(roi_boundary)tumor_area = spc.msmt.getRegionArea(boundary)immune_area = spc.msmt.getRegionArea(immune_boundary)           tumor_immune_overlap = boundary.intersection(immune_boundary)    overlap_area = spc.msmt.getRegionArea(tumor_immune_overlap)           print(f"Area of ROI: {roi_area:.2f}")print(f"Area of main tumor cell region: {tumor_area:.2f}")print(f"Area of immune cell region: {immune_area}")print(f"Area of overlap between tumor and immune cell regions: {overlap_area:.2f}")print(    f"Percentage of tumor region that has overlap with "    f"immune cell region: {overlap_area / tumor_area:.3f}")           识别与免疫细胞相邻的肿瘤细胞。dists = spc.msmt.getMinCellTypesDistance(melano, tcells)adata.obs.loc[    (adata.obs.SOX10_cellRingMask_positive) & (adata.obs.region.isin(["Tumor_ROI", "Tumor"])), "dist"] = diststhreshold = 20adata.obs["dist_binned"] = adata.obs["dist"] <= thresholdinfiltrated = adata.obs[    (adata.obs.SOX10_cellRingMask_positive)        & (adata.obs.region == "Tumor")    & (adata.obs.dist_binned == True)]non_infiltrated = adata.obs[    (adata.obs.SOX10_cellRingMask_positive)    & (adata.obs.region == "Tumor")    & (adata.obs.dist_binned == False)]           fig, ax = plt.subplots(figsize=(10, 6))ax.invert_yaxis()region = adata.obs[(adata.obs.region == "Tumor")]plt.scatter(region["X_centroid"], region["Y_centroid"], s=1, alpha=0.2, color="grey")plt.scatter(    infiltrated["X_centroid"],    infiltrated["Y_centroid"],    s=1,    alpha=0.5,    color="green",    label=f"Infiltrated (distance to t-cells <= {threshold}um)",)    plt.legend(markerscale=10)plt.show()
小结
SpatialCells 是一个用于空间分析多路复用单细胞成像数据的软件包,其特点是能够根据任何细胞组定义感兴趣区域,然后进行基于区域的分析。SpatialCells的功能涵盖了肿瘤微环境分析的各个方面,例如基于区域的细胞组成、肿瘤增殖指数、肿瘤分离指数、免疫细胞浸润和肿瘤免疫距离。SpatialCells 允许使用用户定义的参数以标准化方式预处理和分析数据,并且可以处理包含数百万个细胞的样本。最后大海哥给大家介绍一个云工具!同学们如果觉得自己的代码水平一般,对于很多的参数不知道怎么改,可以体验一下我们的云生信小工具,只需输入数据,即可轻松生成所需图表,字体大小、标题等也可一键更改。感兴趣的小伙伴去云生信(http://www.biocloudservice.com/home.html)体验一下吧!

果叔还提供思路设计、定制生信分析、文献思路复现;有需要的小伙伴欢迎直接扫码咨询果叔,竭诚为您的科研助力!


定制生信分析

服务器租赁

扫码咨询果叔


往期回顾

01

心脏警报,摆烂的年轻人注意了!北大团队10万国人研究:不健康生活方式让冠心病风险激增,你还敢任性吗?

02

网药惊喜!17天接收,速度 “飞” 天!毕业神刊加持,网药+分子对接+分子动力学,2区稳稳哒,中医药学子赶紧的冲!

03

这就是咱们国人之光哇!同济医院骆翔团队以 “UKB 数据库+孟德尔随机化” 斩获一区5分,试问实验还卷得动吗?

04

不会在服务器使用百度网盘?bypy来帮你



生信果
生信入门、R语言、生信图解读与绘制、软件操作、代码复现、生信硬核知识技能、服务器等
 最新文章