# !mkdir data
# !wget http://cf.10xgenomics.com/samples/cell-exp/1.1.0/pbmc3k/pbmc3k_filtered_gene_bc_matrices.tar.gz -O data/pbmc3k_filtered_gene_bc_matrices.tar.gz
# !cd data; tar -xzf pbmc3k_filtered_gene_bc_matrices.tar.gz
# !mkdir write
函数解释:
Preprocessing: pp
Tools: tl
Plotting: pl
# -*- coding: utf-8 -*-
"""
Created on Thu Mar 18 14:15:49 2021
@author: dujidan
"""
import os
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')
results_file = 'write/pbmc3k.h5ad' # the file that will store the analysis results
adata = sc.read_10x_mtx(
'./data/filtered_gene_bc_matrices/hg19/', # the directory with the `.mtx` file
var_names='gene_symbols', # use gene symbols for the variable names (variables-axis index)
cache=True)
adata.var_names_make_unique() # this is unnecessary if using `var_names='gene_ids'` in `sc.read_10x_mtx`
adata
'''
Step1, 数据预处理
'''
# =============================================================================
# Preprocessing
# =============================================================================
# 查看占比最高的 20 个 gene
sc.pl.highest_expr_genes(adata, n_top=20, )
# Basic filtering
sc.pp.filter_cells(adata, min_genes=200)
sc.pp.filter_genes(adata, min_cells=3)
# 线粒体的量是质控的一个重要标准,如果线粒体比例很高,表示细胞质中的 RNA 流失严重。(线粒体较大,更不易流出细胞膜)
adata.var['mt'] = adata.var_names.str.startswith('MT-') # annotate the group of mitochondrial genes as 'mt'
sc.pp.calculate_qc_metrics(adata, qc_vars=['mt'], percent_top=None, log1p=False, inplace=True)
# 计算质量的小提琴图。
sc.pl.violin(adata, ['n_genes_by_counts', 'total_counts', 'pct_counts_mt'], # ['n_genes', 'n_counts', 'percent_mito']
jitter=0.4, multi_panel=True)
# 做一个散点图,也可以直观地显示出一些异常分布的数据点
sc.pl.scatter(adata, x='total_counts', y='pct_counts_mt')
sc.pl.scatter(adata, x='total_counts', y='n_genes_by_counts')
# 删除基因数目太多和线粒体总数过多 的细胞
# 使用切片 进行过滤
adata = adata[adata.obs.n_genes_by_counts < 2500, :] # 线粒体基因占比过多(大于等于0.3)
adata = adata[adata.obs.pct_counts_mt < 5, :] # adata[adata.obs['percent_mito'] < 0.3, :] 线粒体基因占比过多(大于等于0.3)
# 数据标准化,将表达量用对数计算一遍,这样有利于绘图和展示
sc.pp.normalize_total(adata, target_sum=1e4) # counts_per_cell_after=1e4
sc.pp.log1p(adata)
# Identify highly-variable genes
sc.pp.highly_variable_genes(adata, min_mean=0.0125, max_mean=3, min_disp=0.5)
sc.pl.highly_variable_genes(adata)
# filtering 将保守的基因去除,留下差异表达的基因用于后续分析
# 回归每个细胞总计数和线粒体基因表达百分比的影响。将数据放缩到方差为1。
# 单细胞数据集可能包含“不感兴趣”的变异来源。这不仅包括技术噪音,还包括批次效应,甚至包括生物变异来源(细胞周期阶段)。正如(Buettner, et al NBT,2015)中所建议的那样,从分析中回归这些信号可以改善下游维数减少和聚类。
# 这一步高内存需求预警,建议清理电脑缓存,关闭后台不使用的应用。
adata = adata[:, adata.var.highly_variable]
sc.pp.regress_out(adata, ['total_counts', 'pct_counts_mt'])
sc.pp.scale(adata, max_value=10)
'''
Step2, 主成分分析
'''
# =============================================================================
# Principal component analysis
# =============================================================================
# PCA 降维,它揭示了变化的主轴并对数据进行了消噪
sc.tl.pca(adata, svd_solver='arpack')
# 绘图观察, 后面不会使用
sc.pl.pca(adata, color='CST3')
# 让我们观察每一个PC,将使我们知道有多少PC在计算临近关系是应该被考虑在内。
# 作碎石图,观测主成分的质量。这个图用于选择后续应该使用多少个PC,用于计算细胞间的相邻距离。
# 例如:使用聚类sc.tl.louvain() or tSNE sc.tl.tsne()
# 可以粗略的观察PC的数量
sc.pl.pca_variance_ratio(adata, log=True)
#保存结果
adata.write(results_file) # adata.write("write/pca_results.h5ad")
'''
Step3, 聚类分析
'''
# =============================================================================
# Computing the neighborhood graph
# =============================================================================
# 计算细胞间的距离, 先按照默认值设定
sc.pp.neighbors(adata, n_neighbors=10, n_pcs=40)
# 参数说明:
# n_neighbors指的是每个点的邻近点的数量; neighbors的个数越多,聚类数会越少。
# pc的数量依赖于上面所做的碎石图,一般是选在拐点处的的主成分,只需要一个粗略值,不同的pc数量所产生的聚类形状也不同。
# =============================================================================
# Embedding the neighborhood graph
# =============================================================================
# 建议使用UMAP,比tSNE 可以更好反应 多方面的全球连通性,它更好地保留了轨迹。
# 在某些情况下,您仍可能会观察到群集断开连接和类似的连接违规情况
sc.tl.paga(adata) # 注释marker 基因 Annotate the clusters using marker genes.
sc.pl.paga(adata, plot=False) # remove `plot=False` if you want to see the coarse-grained graph
sc.tl.umap(adata, init_pos='paga')
sc.tl.umap(adata)
sc.pl.umap(adata, color=['CST3', 'NKG7', 'PPBP'])
# 进行校正
sc.pl.umap(adata, color=['CST3', 'NKG7', 'PPBP'], use_raw=False)
# =============================================================================
# Clustering the neighborhood graph
# =============================================================================
# 建议使用Leiden图聚类方法(基于优化模块化的社区检测)
# 请注意,Leiden聚类直接对细胞的邻域图进行聚类,这已在上一节中进行了计算。
sc.tl.leiden(adata) # sc.tl.louvain(adata) # sc.pl.umap(adata, color=['louvain'])
sc.pl.umap(adata, color=['leiden', 'CST3', 'NKG7'])
# 保存
adata.write(results_file) # adata.write("umap.h5ad")
# =============================================================================
# Finding marker genes
# =============================================================================
# marker基因通常是细胞表面抗原,用于定义出该细胞的细胞类型。
# 为了定义每个簇属于什么细胞,根据基因的差异表达水平,将每个簇排名前25的基因导出。
# 为此,默认情况下,如果之前已初始化AnnData的.raw 属性,则使用该属性。
# 最简单,最快的方法是t检验。
sc.tl.rank_genes_groups(adata, 'leiden', method='t-test')
sc.pl.rank_genes_groups(adata, n_genes=25, sharey=False)
sc.settings.verbosity = 2 # reduce the verbosity
# Wilcoxon秩和(Mann-Whitney-U)测试的结果非常相似。
# 我们建议在出版物中使用后者,例如参见Sonison&Robinson(2018)。
# 您可能还会考虑功能更强大的差异测试程序包,例如MAST,limma,DESeq2,对于python,则是最新的diffxpy。
sc.tl.rank_genes_groups(adata, 'leiden', method='wilcoxon')
sc.pl.rank_genes_groups(adata, n_genes=25, sharey=False)
# 保存
adata.write(results_file)
# 或者,让我们使用逻辑回归对基因进行排名。例如,Natranos等人已经提出了这一点。(2018)。
# 本质的区别在于,这里我们使用多元变量,而传统的差异检验是单变量。克拉克等。(2014)有更多细节。
sc.tl.rank_genes_groups(adata, 'leiden', method='logreg')
sc.pl.rank_genes_groups(adata, n_genes=25, sharey=False)
# 除了仅通过t检验发现的IL7R和仅通过其他两种方法发现的FCER1A以外,所有标记基因均可以通过所有方法回收。
# Louvain Group Markers Cell Type
# 0 IL7R CD4 T cells
# 1 CD14, LYZ CD14+ Monocytes
# 2 MS4A1 B cells
# 3 CD8A CD8 T cells
# 4 GNLY, NKG7 NK cells
# 5 FCGR3A, MS4A7 FCGR3A+ Monocytes
# 6 FCER1A, CST3 Dendritic Cells
# 7 PPBP Megakaryocytes
# 定义标记基因的列表,以供以后参考。
# 让我们还定义标记基因的列表,以供以后参考。
marker_genes = ['IL7R', 'CD79A', 'MS4A1', 'CD8A', 'CD8B', 'LYZ', 'CD14',
'LGALS3', 'S100A8', 'GNLY', 'NKG7', 'KLRB1',
'FCGR3A', 'MS4A7', 'FCER1A', 'CST3', 'PPBP']
# 重新加载已保存的具有Wilcoxon等级和测试结果的对象。
adata = sc.read(results_file)
pd.DataFrame(adata.uns['rank_genes_groups']['names']).head(5)
# 获取得分和分组列表
result = adata.uns['rank_genes_groups']
groups = result['names'].dtype.names
pd.DataFrame(
{group + '_' + key[:1]: result[key][group]
for group in groups for key in ['names', 'pvals']}).head(5)
# 与单个集群比较
sc.tl.rank_genes_groups(adata, 'leiden', groups=['0'], reference='1', method='wilcoxon')
sc.pl.rank_genes_groups(adata, groups=['0'], n_genes=20)
# 如果我们想要某个组的更详细的视图,请使用sc.pl.rank_genes_groups_violin。
sc.pl.rank_genes_groups_violin(adata, groups='0', n_genes=8)
# 用计算的差分表达式重新加载对象(即,通过与其余组的比较来进行DE):
adata = sc.read(results_file)
sc.pl.rank_genes_groups_violin(adata, groups='0', n_genes=8)
# 如果想比较特定基因和分组
sc.pl.violin(adata, ['CST3', 'NKG7', 'PPBP'], groupby='leiden')
# 标记细胞类型
new_cluster_names = [
'CD4 T', 'CD14 Monocytes',
'B', 'CD8 T',
'NK', 'FCGR3A Monocytes',
'Dendritic', 'Megakaryocytes']
adata.rename_categories('leiden', new_cluster_names)
sc.pl.umap(adata, color='leiden', legend_loc='on data', title='', frameon=False, save='.pdf')
# 现在我们注释了细胞类型,让我们可视化标记基因。
sc.pl.dotplot(adata, marker_genes, groupby='leiden');
# 还有一个非常紧凑的小提琴图。
sc.pl.stacked_violin(adata, marker_genes, groupby='leiden', rotation=90);
# 在此分析过程中,AnnData累积了以下注释。
adata
adata.write(results_file, compression='gzip') # `compression='gzip'` saves disk space, but slows down writing and subsequent reading
adata.raw.to_adata().write('./write/pbmc3k_withoutX.h5ad')
# 如果要导出到“ csv”,则可以使用以下选项:
# Export single fields of the annotation of observations
adata.obs[['n_counts', 'louvain_groups']].to_csv(
'./write/pbmc3k_corrected_louvain_groups.csv')
# Export single columns of the multidimensional annotation
adata.obsm.to_df()[['X_pca1', 'X_pca2']].to_csv(
'./write/pbmc3k_corrected_X_pca.csv')
# Or export everything except the data using `.write_csvs`.
# Set `skip_data=False` if you also want to export the data.
adata.write_csvs(results_file[:-5], )
官网地址: http://scanpy.readthedocs.io/en/latest/index.htm
http://jianshu.com/p/b190efae4d31