栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Scanpy(二)对PBMC3k聚类

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Scanpy(二)对PBMC3k聚类

目录
  • 数据预处理
  • 降维与聚类

数据预处理

我将分析 10X Genomics 免费提供的外周血单核细胞 (PBMC3k) 数据集。 数据为 2700 个单细胞在 Illumina NextSeq 500 上测序;

数据集下载地址:pbmc3k_filtered_gene_bc_matrices

下载后需解压得到以下目录:

|- data
	|- filtered_gene_bc_matrices
		|- hg19
			|- barcodes.tsv
			|- genes.tsv
			|- matrix.mtx

导入相关包:

import numpy as np
import pandas as pd
import scanpy as sc

进行一些设置:

sc.settings.verbosity=3 # verbosity: errors (0), warnings (1), info (2), hints(提示) (3)
sc.logging.print_header()
sc.settings.set_figure_params(dpi=80,facecolor='white')
result_file='./write/pbmc3k.h5ad' # 用于缓存分析结果

读入PBMC3k数据集:

adata=sc.read_10x_mtx(
    './data/filtered_gene_bc_matrices/hg19/', # .mtx文件的所在目录
    var_names='gene_symbols', # 使用gene_symbols作为AnnData的特征名称
    cache=True) # 写入缓存便于快速读写

adata.var_names_make_unique() # 如果在 sc.read_10x_mtx 中使用 var_names='gene_ids',这是不必要的
print(adata)
"""
AnnData object with n_obs × n_vars = 2700 × 32738
    var: 'gene_ids'
"""

针对AnnData的特征(基因),统计每个基因在所有细胞中的分布,并绘制这些基因分布的箱型图:

sc.pl.highest_expr_genes(adata,n_top=20)


使用两个工具:sc.pp.filter_cells进行细胞的过滤,sc.pp.filter_genes进行基因的过滤。这两个工具的说明可回顾Scanpy(一)AnnData数据结构与一些API用法介绍;过滤过程如下:

sc.pp.filter_cells(adata,min_genes=200)
sc.pp.filter_genes(adata,min_cells=3)

上面过程为基因过滤(Basic filtering),下面我需要收集关于线粒体基因(mitochondrial genes)的信息,这些信息对质量控制(Quality Control,QC)很重要。

我们需要过滤包含线粒体基因和基因过多的细胞,因为:

  • 检测出高比例的线粒体基因,表明细胞的测量质量较差;
  • 表达基因过多可能是由于一个测量油滴包裹了多个细胞,从而检测出比正常情况要多的基因数,因此要过滤这些细胞。

首先,查看数据的特征量(AnnData.var):

print(adata.var)
"""
                      gene_ids  n_cells
AL627309.1     ENSG00000237683        9
...                        ...      ...
SRSF10-1       ENSG00000215699       69
"""

对于var这个Dataframe的第0列,也就是index(基因名称),也被称为var_names,现在我们要为var中的基因做标记,判断哪些基因是线粒体相关的:

# startswith()方法用于检查字符串是否是以指定子字符串开头, 如果是则返回 True, 否则返回 False
adata.var['mt']=adata.var_names.str.startswith('MT-') # var新增一列'mt', 这是用于标记基因是否是线粒体相关的一个mask

使用 pp.calculate_qc_metrics,我们可以计算许多QC指标:

sc.pp.calculate_qc_metrics(adata,qc_vars=['mt'],percent_top=None,log1p=False,inplace=True)

扩展部分:QC与sc.pp.calculate_qc_metrics

在单细胞分析中,我们通常要对某些基因计算数据指标,根据指标过滤数据,以便保证后续计算的质量,这就是质量控制;

sc.pp.calculate_qc_metrics是用于计算QC指标的函数:

sc.pp.calculate_qc_metrics(data, 
						   qc_vars=(), 
						   percent_top=(50, 100, 200, 500), 
						   inplace=False, 
						   log1p=True)

参数说明:

  • data:Anndata;
  • qc_vars:用于标识要控制的特征(基因),布尔型元素,用于作为mask使用;
  • percent_top:计算与常出现基因的比,percent_top=[50] 计算与第 50 个最常出现基因的比例,None则不计算;
  • inplace:决定是否将计算指标添加到var和obs中;
  • log1p:设置为False可以跳过转换到log1p空间的过程;log1p即log(1+number),用于压缩数据并确保结果是一个正数;

实例如下:

import seaborn as sns
import matplotlib.pyplot as plt

pbmc=sc.datasets.pbmc3k() # 自动下载到./data/pbmc3k_raw.h5ad

# 标记线粒体基因, 并保存为 mask
pbmc.var['mito']=pbmc.var_names.str.startswith('MT-')
print(pbmc.var)
"""
                      gene_ids   mito
index                                
MIR1302-10     ENSG00000243485  False
...                        ...    ...
AC002321.1     ENSG00000215611  False
"""
print(pbmc.var.columns)
"""
Index(['gene_ids', 'mito'], dtype='object')
"""
print(pbmc.obs.columns)
"""
Index([], dtype='object')

此时obs只有index, obs的index为细胞的名称
"""

# 计算线粒体基因的 QC 指标
sc.pp.calculate_qc_metrics(pbmc,qc_vars=['mito'],inplace=True)
print(pbmc.var.columns) # 关于基因轴上的QC指标
"""
Index(['gene_ids', 'mito', 'n_cells_by_counts', 'mean_counts',
       'log1p_mean_counts', 'pct_dropout_by_counts', 'total_counts',
       'log1p_total_counts'],
      dtype='object')
"""
print(pbmc.obs.columns) # 关于细胞轴上的QC指标
"""
Index(['n_genes_by_counts', 'log1p_n_genes_by_counts', 'total_counts',
       'log1p_total_counts', 'pct_counts_in_top_50_genes',
       'pct_counts_in_top_100_genes', 'pct_counts_in_top_200_genes',
       'pct_counts_in_top_500_genes', 'total_counts_mito',
       'log1p_total_counts_mito', 'pct_counts_mito'],
      dtype='object')
"""

# 对obs中的计算指标可视化
sns.jointplot(data=pbmc.obs,
              x="log1p_total_counts",
              y="log1p_total_counts_mito",
              kind="hex")
plt.show()
sns.histplot(pbmc.obs["pct_counts_mito"])
plt.show()

total_counts记录了对每个细胞,所包含基因的总数;

total_counts_mito记录了对每个细胞,所包含控制基因(qc_vars中列出的基因)的总数;

pct_counts_mito记录了对每个细胞,含线粒体的基因总数;(其中 ‘mito’ 来自var中的index)


现在,我们用小提琴图可视化两个QC指标:

# jitter 表示抖动
sc.pl.violin(adata, ['pct_counts_mt'], jitter=0.4)
sc.pl.violin(adata, ['n_genes_by_counts'], jitter=0.4)



从上面两个指标可以看出,大部分细胞的线粒体基因数在5以下,大部分细胞的基因总数在2500以下,所以我们要过滤掉那些异常的细胞:

# 去除线粒体基因过多或基因总数过多的细胞
adata = adata[adata.obs.n_genes_by_counts < 2500, :]
adata = adata[adata.obs.pct_counts_mt < 5, :]

然后对数据标准化,并转换到 log1p 空间:

# 标准化
sc.pp.normalize_total(adata, target_sum=1e4)

# 压缩到logp1空间
sc.pp.log1p(adata)

确定高变基因并过滤数据:

# 确定高变基因
sc.pp.highly_variable_genes(adata)
"""
extracting highly variable genes
    finished (0:00:00)
--> added
    'highly_variable', boolean vector (adata.var) # 布尔型mask
    'means', float vector (adata.var)
    'dispersions', float vector (adata.var)
    'dispersions_norm', float vector (adata.var)
"""

# 根据高变基因过滤数据
adata=adata[:,adata.var.highly_variable]

对数据进行回归并校正数据:

"""
sc.pp.regress_out(data, keys)
keys:要回归的data.obs中的数据列
"""
# 回归 adata.obs 中的列 (columns)
sc.pp.regress_out(adata, ['total_counts', 'pct_counts_mt'])

将数据adata.X缩放到单位方差和零均值,对于缩放后的数据,在值为10处截断:

sc.pp.scale(adata, max_value=10)
降维与聚类

我们可以用PCA进行降维:

# PCA降维并可视化
sc.tl.pca(adata, svd_solver='arpack')
sc.pl.pca(adata, color='CST3')

# 写入缓存
adata.write(result_file)


sc.tl.pca
使用PCA对数据进行变换;

sc.pl.pca

sc.pl.pca(adata,color=None)

注意参数color,我们可以传递adata中的'ann1' or ['ann1', 'ann2'],这些ann可以是基因,可以是聚类结果,所以我们可以根据基因标记颜色,也可以根据聚类算法结果标记颜色;

tl用于做变换,pl用于可视化(只取前2个维度),调用pl前需要先找到tl计算得到的数据空间;


比如上图,PCA将高维数据adata.X聚类到2维空间后得到的只是一些平面下的散点,但我们可以根据每个散点(细胞)中包含基因CST3的数量为散点标记颜色。

我们也可以用UMAP进行降维并可视化,我们现在使用的数据是经过PCA变换后的数据(保留了所有成分),使用这个数据并用UMAP方法做变换:

# UMAP 降维得到 embedding 并可视化
sc.pp.neighbors(adata,n_neighbors=10,n_pcs=40)
sc.tl.umap(adata)
sc.pl.umap(adata, color=['CST3', 'NKG7', 'PPBP'])


现在,利用经过UMAP变换后的数据,使用 leiden 方法进行聚类:

# 用 leiden 方法聚类
sc.tl.leiden(adata)
"""
running Leiden clustering
    finished: found 8 clusters and added
    'leiden', the cluster labels (adata.obs, categorical) (0:00:00)
"""
print(adata.obs)
"""
                  n_genes  n_genes_by_counts  ...  pct_counts_mt  leiden
AAACATACAACCAC-1      781                779  ...       3.017776       0
AAACATTGAGCTAC-1     1352               1352  ...       3.793596       2
...                   ...                ...  ...            ...     ...
TTTGCATGCCTCAC-1      724                723  ...       0.806452       0
"""

# 用 UMAP 可视化聚类结果
sc.pl.umap(adata, color='leiden')

# 写入结果
adata.write(result_file)

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/303011.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号