Tangram 空间转录组教程(一)

什么是tangram?

tangram是一种映射单细胞表达谱数据到空间表达谱的方法,它收集同一解剖区域或者组织类型的单细胞数据和空间数据。通过整合,该方法在scRNAseq表达谱匹配的基础上创建一组新的空间转录组数据,并可投射scRNAseq的注释(e.g.细胞类型、模块)到不同的空间区域。

使用Tangram可以做什么?

Tangram最常用的功能是在空间中分辨细胞类型,并对空间转录组数据进行校正:因为相较于空间转录组(Visium 或 Slide-seq),scRNA-seq数据较少出现dropout. Tangram可以生成一组包含更多基因的空间转录谱,因此,我们可以在空间上观察转录模块(program)的表达,以此来发现配受体互作和细胞通讯连接机制。在细胞分割允许的情况下,Tangram还可以用来对空间数据去卷积。如果碰到多模态的单细胞数据,Tangram还可以在空间上可视化其他模态数据,比较染色质开放性(chromatin accessibility).

Tangram和其他空间去卷积/映射方法的不同?

验证性。其他方法通过已知的细胞类型分布模式或者频率来验证映射的合理性,做的都是sanity checks(合理性检查),但如用于探索性研究将不再有用。而tangram的好处是映射结果可以通过holdout genes(预留出的基因/test transcriptome)来进行检验。

当scRNAseq和spatial data 来自不同的样本,可以用tangram吗?

可行的。发明者对映射方法进行了很巧妙的调整,可以对某一细胞类型的average cells进行映射,而不是只映射单个细胞,这种平均的方式可以消除不同样本带来的生物信号变化。记住,这需要再scRNA-seq前进行注释来牺牲单细胞的高分辨度,并对函数传入mode = cluster.

不多说了,上代码

import squidpy as sq
import numpy as np
import pandas as pd
from anndata import AnnData
import pathlib
import matplotlib.pyplot as plt
import matplotlib as mpl
import skimage
import seaborn as sns
import tangram as tg

sc.logging.print_header()
print(f"squidpy=={sq.__version__}")

%load_ext autoreload
%autoreload 2
%matplotlib inline

加载数据

  • Squidy加载小鼠大脑皮层的单细胞数据为adata_sc,空间转录组数据为adata_st.
  • 只剪取包含大脑皮层的clusters, 单细胞数据的预处理步骤参考:cite:tasic2018shared
adata_st = sq.datasets.visium_fluo_adata_crop()
adata_st = adata_st[
    adata_st.obs.cluster.isin([f"Cortex_{i}" for i in np.arange(1, 5)])
].copy()
img = sq.datasets.visium_fluo_image_crop()
adata_sc = sq.datasets.sc_mouse_cortex()

可视化空间和单细胞数据

adata_st.obs
fig, axs = plt.subplots(1, 2, figsize=(20, 5))
sc.pl.spatial(
    adata_st, color="cluster", alpha=0.7, frameon=False, show=False, ax=axs[0]
)
sc.pl.umap(
    adata_sc, color="cell_subclass", size=10, frameon=False, show=False, ax=axs[1]
)
plt.tight_layout()
图片.png

使用Tangram进行空间映射前要先确定一组训练基因,数目在100-1000个之间,并具有高的信号质量。有时候可以通过改变不同的候选训练集印记来观察结果的变化。
在这里,我们使用了1401个标记基因作为训练基因集(标记基因选取为每群细胞特异表达的前100个基因)

sc.tl.rank_genes_groups(adata_sc, groupby="cell_subclass", use_raw=False)
markers_df = pd.DataFrame(adata_sc.uns["rank_genes_groups"]["names"]).iloc[0:100, :]
markers = list(np.unique(markers_df.melt().value.values))
len(markers)

接着我们使用下面一组函数传入训练基因集, 函数对基因进行筛选,如果改基因在两个数据集中全部是0值,或者不同时出现在两个数据集,该基因将被去除。

tg.pp_adatas(adata_sc, adata_st, genes=markers)

两个数据集从1401个基因中筛选得到1280个。

Find alignment
为了对scRNA-seq表达谱进行最佳的空间匹配,使用map_cells_to_space函数:-num_epochs确定映射迭代次数;随着不断地迭代,当评分进入平台期程序随之停止,评分基于mapped cells vs spatial data之间训练基因集表达的相似性。

  • 默认的mapping mode 是mode='cells',这推荐用于GPU环境。
  • 也可用mode='clusters',它将同一cluster的细胞进行平均,使用cluster_label传入标签,速度更快,并适用于空间数据和单细胞数据来自不同样本。
    -使用uniform参数如果spatial voxels是单细胞分辨率(例如MERFISH)
    -rna_count_based默认spot中细胞密度与RNA分子数目是呈线性相关的。
ad_map = tg.map_cells_to_space(adata_sc, adata_st,
    mode="cells",
#     mode="clusters",
#     cluster_label='cell_subclass',  # .obs field w cell types
    density_prior='rna_count_based',
    num_epochs=500,
    # device="cuda:0",
    device='cpu',
)

映射后的ad_map储存成AnnData格式,具有如下的结构:

  • The cell-by-spot matrix X contains the probability of cell i to be in spot j.
  • The obs dataframe contains the metadata of the single cells.
  • The var dataframe contains the metadata of the spatial data.
  • The uns dictionary contains a dataframe with various information about the training genes (saved as train_genes_df).

细胞类型映射
接着,使用project_cell_annotation将细胞类型注释映射到空间中,并用plot_cell_annotation可视化,perc来设定colormap的范围以去除离群值。

tg.project_cell_annotations(ad_map, adata_st, annotation="cell_subclass")
annotation_list = list(pd.unique(adata_sc.obs['cell_subclass']))
tg.plot_cell_annotation_sc(adata_st, annotation_list,perc=0.02)
图片.png

接着检验mapping是否成功,在每个基因水平,如果想查看每个基因的simlarity scores,使用ad_map.uns['train_genes_df']查看

tg.plot_training_scores(ad_map, bins=20, alpha=.5)
图片.png

New spatial data via aligned single cells

如果mapping mode 是mode='cells',我们可以生成一个新的包含经匹配单细胞的数据,该函数project_genes接受ad_map以及相应的单细胞矩阵adata_sc作为输入。得到的ad_ge是voxel-by-gene AnnData,与adata_st近似,但是包含mapped single cell单细胞的表达矩阵而不是Visium,接下来的分析都围绕ad_ge

ad_ge = tg.project_genes(adata_map=ad_map, adata_sc=adata_sc)
ad_ge
  • 这里的ad_ge: AnnData object with n_obs × n_vars = 324 × 36826
  • 而ad_map: AnnData object with n_obs × n_vars = 21697 × 324
    注意两者区别:
    ad_map的n_obs表示单细胞数据中的不同细胞,显示其在spot中的概率。
    ad_ge的n_obs表示不同spot,n_vars代表不同基因,表示单细胞mapped之后新的空间矩阵。

挑选几个评分低的tranning gene

genes = ['rragb', 'trim17', 'eno1b']
ad_map.uns['train_genes_df'].loc[genes]

使用plot_genes函数传入两个voxel-by-gene AnnData,分别是adata_measured实际检测的空间矩阵adata_st,以及上一步得到的预测的空间矩阵adata_predicted: ad_ge

tg.plot_genes_sc(genes, adata_measured=adata_st, adata_predicted=ad_ge, perc=0.02)
图片.png

以上结果可以解释为什么这些基因的类似评分较低。因为有些基因在不同检测技术下具有不同的程度的稀疏度(sparity),通常scRNA-seq的稀疏性相较于空间转录组更高。由于空间转录组技术存在dropouts效应,由于某些基因信号缺陷,Tangram不能很好得在空间上对这些基因进行匹配。但只要这些tranning基因有较高的测量质量,我们可以相信映射的结果并使用tangram预测其在空间位置上的表达。
我们也可以用这种插值方法推断一些没有通过空间技术检测到的基因的表达,前提是这些基因通过单细胞测序检测到。

genes=['loc102633833', 'gm5700', 'gm8292']
tg.plot_genes_sc(genes, adata_measured=adata_st, adata_predicted=ad_ge, perc=0.02)

图片.png

目前,我们只是检验用来匹配数据的training genes,但是the mapped single cell data ad_gene包含所有的转录谱,约有35,000基因。(ad_ge.var.is_training == False).sum()来得到基因数量。我们可以通过plot_genes对这些test_genes进行探索,这是验证我们映射成果的必要方式。

也可以通过compare_spatial_geneexp对所有基因similarity scores进行计算,需要传入不同的两个空间矩阵ad_ge和adata_st,Training genes会在is_training列用布尔值标记。如果我们也传入single cell AnnData,函数将返回sparsity_sc (single cell data sparsity) 和sparsity_diff (spatial data sparsity - single cell data sparsity) 两列值,用于plot_test_scores作图。

df_all_genes = tg.compare_spatial_geneexp(ad_ge, adata_st, adata_sc)
df_all_genes

test_genes的预测情况可以可视化:

# sns.scatterplot(data=df_all_genes, x='score', y='sparsity_sp', hue='is_training', alpha=.5);  # for legacy
tg.plot_auc(df_all_genes);
图片.png

这张图是tangram中用于检验验证基因效果最重要的图。图中每个点代表一个基因,x轴表示基因的相似性评分,y轴表示基因在空转数据中的稀疏性。不出所料,高稀疏性的基因相似性评分较低,证明tangram在test genes中有较佳的预测效果。我们可以用曲线下面积去评估预测效果。

以下这些基因稀疏性高,但能很好得预测出来。

genes=['tfap2b', 'zic4']
tg.plot_genes_sc(genes, adata_measured=adata_st, adata_predicted=ad_ge, perc=0.02)
图片.png

某些非稀疏基因呈现出特异的表达模式,tangram可以更加凸显这一模式。

genes = ['cd34', 'rasal1']
tg.plot_genes_sc(genes, adata_measured=adata_st, adata_predicted=ad_ge, perc=0.02)
图片.png

有些基因没有深入阐明功能,很难通过空转技术检测到,而tangram可以提供预测。

genes = ['gm33027', 'gm5431']
tg.plot_genes_sc(genes[:5], adata_measured=adata_st, adata_predicted=ad_ge, perc=0.02)
图片.png

你可能感兴趣的:(Tangram 空间转录组教程(一))