多样本数据的自动注释-harmony和celltypist

科技   2024-11-15 13:35   广东  
 今天是生信星球陪你的第1021天

   
公众号里的文章大多数需要编程基础,如果因为代码看不懂,而跟不上正文的节奏,可以来找我学习,相当于给自己一个新手保护期。我的课程都是循环开课,点进去咨询微信↓
生信分析直播课程(每月初开一期,春节休一个月)
生信新手保护学习小组(每月两期)
单细胞陪伴学习小组(每月两期)

1.R包准备和数据读取

# pip install scanpy==1.9.3  -i https://pypi.tuna.tsinghua.edu.cn/simple
# pip install leidenalg scikit-misc -i https://pypi.tuna.tsinghua.edu.cn/simple

import scanpy as sc
import os
import pandas as pd
from scipy.io import mmread
import anndata

path1='04_data/'
os.listdir(path1)
['TD1''TD2''TD3']
os.listdir('04_data/TD1/')
['barcodes.tsv.gz''features.tsv.gz''matrix.mtx.gz']

如上所见,工作目录下的04_data文件夹下有3个子文件夹,每个文件夹里是3个标准文件

读取单个样本数据的代码先跑通,然后才能搞个循环批量读取

adata = sc.read_10x_mtx(
    path1+os.listdir(path1)[0],  # the directory with the `.mtx` file
    var_names="gene_symbols",  # use gene symbols for the variable names (variables-axis index)
    cache=True,  # write a cache file for faster subsequent reading
)
adata.var_names_make_unique()  
# this is unnecessary if using `var_names='gene_ids'` in `sc.read_10x_mtx`
adata
AnnData object with n_obs × n_vars = 15216 × 33538
    var: 'gene_ids''feature_types'

python里面不能直接写1:3这样的向量单独使用,只有取子集时才能这样用。单独使用连续的数字要写:

list(range(3))
[0, 1, 2]

用for循环批量读取数据,并顺便输出每个数据的行列数:

adata = {}
for i in range(len(os.listdir(path1))):
    data = sc.read_10x_mtx(path1 +os.listdir(path1)[i], var_names="gene_symbols", cache=True)
    data.var_names_make_unique()  
    adata[os.listdir(path1)[i]] = data
    print([f'{os.listdir(path1)[i]}:done']+list([data.shape]))
['TD1:done', (15216, 33538)]
['TD2:done', (18064, 33538)]
['TD3:done', (12658, 33538)]

把多个数据拼接到一起,成为一个大的anndata对象

adata=sc.concat(adata,label='batch')
adata.obs_names_make_unique()
adata
AnnData object with n_obs × n_vars = 45938 × 33538
    obs: 'batch'
adata.obs.batch.value_counts() #每个样本里的细胞数量
batch
TD2    18064
TD1    15216
TD3    12658
Name: count, dtype: int64

2.质控

sc.pp.filter_cells(adata,min_genes=300)
sc.pp.filter_genes(adata,min_cells=5)
#计算线粒体基因比例
adata.var['mt']=adata.var_names.str.startswith('MT-')
# 计算核糖体基因比例
adata.var['ribo']=adata.var_names.str.match('^RP[SL]')
# 计算红血细胞基因比例
adata.var['hb']=adata.var_names.str.match('^HB[^(P)]')
sc.pp.calculate_qc_metrics(adata,qc_vars=['mt','ribo','hb'],percent_top=None,log1p=False,inplace=True)
# 可视化细胞的上述比例情况

sc.pl.violin(adata,['n_genes_by_counts','total_counts'],groupby='batch',jitter=False)
sc.pl.violin(adata,['pct_counts_mt''pct_counts_ribo','pct_counts_hb'],groupby='batch',xlabel='sample',jitter=False)
sc.pl.scatter(adata,x='total_counts',y='n_genes_by_counts',color='batch')

adata = adata[adata.obs.n_genes_by_counts < 6000, :]
adata = adata[adata.obs.pct_counts_mt < 18, :].copy()

3.常规的降维聚类流程

celltypist包需要的数据是log normlize之后的数据,会使用这里的adata.raw。

sc.pp.normalize_total(adata,target_sum=1e4)
sc.pp.log1p(adata)
adata.raw = adata.copy()
#celltypist包需要的数据是log normlize之后的数据,会使用这里的adata.raw。
sc.pp.highly_variable_genes(adata,flavor='seurat_v3',n_top_genes=2000)
sc.pp.scale(adata)
sc.tl.pca(adata,use_highly_variable=True)
sc.external.pp.harmony_integrate(adata,'batch')
#聚类
sc.pp.neighbors(adata,use_rep='X_pca_harmony',n_pcs=15)
sc.tl.umap(adata)
2024-11-15 13:02:16,497 - harmonypy - INFO - Computing initial centroids with sklearn.KMeans...
Computing initial centroids with sklearn.KMeans...
2024-11-15 13:02:18,831 - harmonypy - INFO - sklearn.KMeans initialization complete.
sklearn.KMeans initialization complete.
2024-11-15 13:02:19,329 - harmonypy - INFO - Iteration 1 of 10
Iteration 1 of 10
2024-11-15 13:02:35,549 - harmonypy - INFO - Iteration 2 of 10
Iteration 2 of 10
2024-11-15 13:02:51,986 - harmonypy - INFO - Iteration 3 of 10
Iteration 3 of 10
2024-11-15 13:03:08,223 - harmonypy - INFO - Iteration 4 of 10
Iteration 4 of 10
2024-11-15 13:03:24,727 - harmonypy - INFO - Iteration 5 of 10
Iteration 5 of 10
2024-11-15 13:03:34,032 - harmonypy - INFO - Iteration 6 of 10
Iteration 6 of 10
2024-11-15 13:03:40,914 - harmonypy - INFO - Iteration 7 of 10
Iteration 7 of 10
2024-11-15 13:03:47,042 - harmonypy - INFO - Iteration 8 of 10
Iteration 8 of 10
2024-11-15 13:03:53,211 - harmonypy - INFO - Converged after 8 iterations
Converged after 8 iterations
sc.tl.leiden(adata, flavor="igraph", n_iterations=2,resolution=0.5)
sc.pl.umap(adata,color='leiden',legend_loc='on data')



4.完成注释

import celltypist
from celltypist import models
model = models.Model.load(model='Immune_All_High.pkl'#https://www.celltypist.org/models
model
predictions = celltypist.annotate(adata, model = model, majority_voting = True)
predictions.predicted_labels
👀 Invalid expression matrix in `.X`, expect log1p normalized expression to 10000 counts per cell; will use `.raw.X` instead
🔬 Input data has 43649 cells and 23244 genes
🔗 Matching reference genes in the model
🧬 5842 features used for prediction
⚖️ Scaling input data
🖋️ Predicting labels
✅ Prediction done!
👀 Detected a neighborhood graph in the input object, will run over-clustering on the basis of it
⛓️ Over-clustering input data with resolution set to 20
🗳️ Majority voting the predictions
✅ Majority voting done!
adata2 = predictions.to_adata()
adata2.obs
adata2.obs.majority_voting = adata2.obs.majority_voting.str.replace(' cells''', regex=False)
adata2.obs.majority_voting = adata2.obs.majority_voting.str.replace(' monocytes'' Mono', regex=False)
adata2.obs.majority_voting
AAACCCAAGACCTTTG-1              T
AAACCCAAGCCTGAAG-1     Epithelial
AAACCCAAGCTGTGCC-1              T
AAACCCAAGGCCACTC-1              T
AAACCCAAGGGTTAAT-1              T
                         ...     
TTTGTTGCAGCGACAA-1            ILC
TTTGTTGCATCCGATA-1              T
TTTGTTGTCAGCGGAA-1    Endothelial
TTTGTTGTCCAACTGA-1            ILC
TTTGTTGTCGGAACTT-1            ILC
Name: majority_voting, Length: 43649, dtype: object
sc.tl.umap(adata2)
sc.pl.umap(adata2, color = 'majority_voting',legend_loc="on data")
... storing 'majority_voting' as categorical

5.画个好看点的图

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import numpy as np

umap_coords = adata2.obsm['X_umap']
labels = adata2.obs['majority_voting']
plt.figure(figsize=(6,5))
unique_labels = labels.unique()
colors = plt.cm.get_cmap('Accent', len(unique_labels))  
original_colors = plt.cm.Set1(np.linspace(019))

# 使用LinearSegmentedColormap.from_list创建一个新的颜色映射,包含100种渐变色
colors = mcolors.LinearSegmentedColormap.from_list('colors', original_colors, N=len(unique_labels))
for i, label in enumerate(unique_labels):
    plt.scatter(umap_coords[labels == label, 0], umap_coords[labels == label, 1], 
                color=colors(i),s=1,alpha = 0.4)
for label in unique_labels:
    label_coords = umap_coords[labels == label]
    center_x = label_coords[:, 0].mean()
    center_y = label_coords[:, 1].mean()
    plt.text(center_x, center_y, label, fontsize=10, ha='center', va='center')
plt.grid(False)
plt.title('majority_voting', fontsize=14)
plt.xlabel('UMAP 1', fontsize=12)
plt.ylabel('UMAP 2', fontsize=12)
plt.show()





生信星球
一个零基础学生信的平台-- 原创结构化图文/教程,精选阶段性资料,带你少走弯路早入门,收获成就感,早成生信小能手~
 最新文章