ixxmu / mp_duty

抓取网络文章到github issues保存
https://archives.duty-machine.now.sh/
115 stars 30 forks source link

还没见过ComplexHeatmap版本的单细胞数据Dotplot图?大海哥手把手教你绘制! #5144

Closed ixxmu closed 3 months ago

ixxmu commented 3 months ago

https://mp.weixin.qq.com/s/tDPW1h9ELPJn8mtHkZ85bw

ixxmu commented 3 months ago

还没见过ComplexHeatmap版本的单细胞数据Dotplot图?大海哥手把手教你绘制! by 生信滩

小伙伴做单细胞数据可视化的时候,做过不少的图,热图肯定也少不了绘制,之前大海哥教过小伙伴如何使用ComplexHeatmap绘制出精美的热图,那么我们是不是可以把这个方式套用到单细胞数据中来呢,大海哥这里就手把手教小伙伴利用ComplexHeatmap去绘制单细胞数据中复杂的Dotplot图!
其实Dotplot就是点图,而点图是可以跨细胞群可视化 scRNAseq 表达数据的的好方法之一。它提供了细胞群内细胞的平均表达水平的信息(按颜色)以及群内表达该基因的细胞的百分比(按点的大小)。所以呢,在单细胞数据点图是一种常用的方式,但是常规的Seurat::DotPlot()绘图方式,不能对行和列进行聚类,所以这次大海哥使用ComplexHeatmap进行绘制,来看看吧!
我们使用自带的数据集,先调用R包
library(Seurat)  # DotPlot()library(tidyverse)  # 数据整理library(ComplexHeatmap)  # 绘制气泡热图library(circlize)  # circlize::colorRamp2()library(scRNAtoolVis)  # 为了使用pbmc数据集然后我们加载pbmc数据集httest <- system.file("extdata", "htdata.RDS", package = "scRNAtoolVis")pbmc <- readRDS(httest)           # add groupspbmc$groups <- rep(c('stim','control'),each = 1319)    # add celltypepbmc$celltype <- Seurat::Idents(pbmc)           # load markergenedata("top3pbmc.markers")           # checkhead(top3pbmc.markers,3)
先看看用Seurat::DotPlot()绘制的图
p <- DotPlot(object = pbmc, features = top3pbmc.markers$gene)p

   
在一些细节上我们无法修改,来我们看看ComplexHeatmap版的Dotplot,先提取绘图数据        

 

#提取数据df<- p$data           exp_mat <- df %>%  dplyr::select(-pct.exp, -avg.exp) %>%  pivot_wider(names_from = id, values_from = avg.exp.scaled) %>%  as.data.frame()                      row.names(exp_mat) <- exp_mat$features.plotexp_mat <- exp_mat[,-1] %>% as.matrix()head(exp_mat)
数据2
#数据2               percent_mat <- df %>%  dplyr::select(-avg.exp, -avg.exp.scaled) %>%  pivot_wider(names_from = id, values_from = pct.exp) %>%  as.data.frame()           row.names(percent_mat) <- percent_mat$features.plotpercent_mat <- percent_mat[,-1] %>% as.matrix()head(percent_mat)
小伙伴可以按照这样的数据形式自行去设置
然后我们去设置一下调色板       

 

#调色板library(RColorBrewer)quantile(exp_mat, c(0.1, 0.5, 0.9, 0.99))           col_fun = circlize::colorRamp2(c(-0.6, 0, 2), brewer.pal(11, "PiYG")[c(11,8,1)])           cell_fun = function(j, i, x, y, w, h, fill){  grid.rect(x = x, y = y, width = w, height = h,            gp = gpar(col = NA, fill = NA))      grid.circle(x=x,y=y,r= percent_mat[i, j]/100 * min(unit.c(w, h)),              gp = gpar(fill = col_fun(exp_mat[i, j]), col = NA))}
这里我们使用ComplexHeatmap::Heatmap绘制聚类散点图(想象一下吧,就是把热图中的小方块换成了圆块),看一下效果
Heatmap(exp_mat,        name = "hp",        heatmap_legend_param = list(title = "expression"),        col = col_fun,        rect_gp = gpar(type = "none"),        cell_fun = cell_fun,        row_names_gp = gpar(fontsize = 5),        row_km = 4,        border = "black")
但是还有很多细节不是很完美,仔细看行列名称不清楚距离也很宽,下面我们对配色还有网络以及行的修饰进行修改一下,来看看    
还是和上面一样把数据调用出来
httest <- system.file("extdata", "htdata.RDS", package = "scRNAtoolVis")pbmc <- readRDS(httest)           # add groupspbmc$groups <- rep(c('stim','control'),each = 1319)# add celltypepbmc$celltype <- Seurat::Idents(pbmc)           # load markergenedata("top3pbmc.markers")           # checkhead(top3pbmc.markers,3)# Seurat::DotPlot()p <- DotPlot(object = pbmc, features = top3pbmc.markers$gene)下面重新整理绘图的数据# 提取并重新整理绘图数据df<- p$data           exp_mat <- df %>%  dplyr::select(-pct.exp, -avg.exp) %>%      pivot_wider(names_from = id, values_from = avg.exp.scaled) %>%  as.data.frame()row.names(exp_mat) <- exp_mat$features.plotexp_mat <- exp_mat[,-1] %>% as.matrix()           percent_mat <- df %>%  dplyr::select(-avg.exp, -avg.exp.scaled) %>%  pivot_wider(names_from = id, values_from = pct.exp) %>%  as.data.frame()           row.names(percent_mat) <- percent_mat$features.plotpercent_mat <- percent_mat[,-1] %>% as.matrix()           # 填充色设置col_fun = circlize::colorRamp2(c(-0.6, 0, 2), c("#424da7","#ffffff","#dd2b19"))           # 增加细胞百分比和细胞群注释cluster <- colnames(exp_mat)           column_ha <- HeatmapAnnotation(  cluster = cluster,  col = list(cluster = setNames(brewer.pal(9, "Paired"), unique(cluster))      ),  na_col = "grey")           # 图层设置layer_fun = function(j, i, x, y, w, h, fill){  grid.rect(x = x, y = y, width = w, height = h,            gp = gpar(col = NA, fill = NA))  grid.circle(x=x,y=y,r= pindex(percent_mat, i, j)/100 * unit(2, "mm"),              gp = gpar(fill = col_fun(pindex(exp_mat, i, j)), col = NA))}           # 图例设置lgd_list = list(  Legend( labels = c(0,0.25,0.5,0.75,1), title = "pt",          graphics = list(            function(x, y, w, h) grid.circle(x = x, y = y, r = 0 * unit(2, "mm"),                                             gp = gpar(fill = "black")),            function(x, y, w, h) grid.circle(x = x, y = y, r = 0.25 * unit(2, "mm"),                                             gp = gpar(fill = "black")),            function(x, y, w, h) grid.circle(x = x, y = y, r = 0.5 * unit(2, "mm"),                                             gp = gpar(fill = "black")),            function(x, y, w, h) grid.circle(x = x, y = y, r = 0.75 * unit(2, "mm"),                                                 gp = gpar(fill = "black")),            function(x, y, w, h) grid.circle(x = x, y = y, r = 1 * unit(2, "mm"),                                             gp = gpar(fill = "black")))  ))上述设置好了之后,我们开始绘制图片,先看一下气泡热图# 气泡热图hp <- Heatmap(exp_mat,              name = "hp",              heatmap_legend_param = list(title = "expression"),              col = col_fun,              rect_gp = gpar(type = "none"),              layer_fun = layer_fun,              row_names_gp = gpar(fontsize = 5),              row_names_side = "left",              row_title = NULL,              row_km = 4,              column_names_rot = 45,              border = "black",              bottom_annotation = column_ha,              # 去掉行聚类树的虚线              show_parent_dend_line = F)               draw(hp, annotation_legend_list = lgd_list)
是不是很好看,并且图注信息等很清楚,配色也是很美丽。
下面在修饰一下行的名字等,
# 装饰行namedecorate_row_names("hp", {  grid.rect(gp = gpar(fill = "#FFA50080", col = "white"))}, slice = 1)
decorate_row_names("hp", {  grid.rect(gp = gpar(fill = "#FF000040", col = "white"))}, slice = 2)
   
decorate_row_names("hp", {  grid.rect(gp = gpar(fill = "#00FF0040", col = "white"))}, slice = 3)
   
decorate_row_names("hp", {  grid.rect(gp = gpar(fill = "#0000FF40", col = "white"))}, slice = 4)
   
好了,这样一来图片就绘制完成了,小伙伴有没有学会呢?快去动手试试吧,多多理解代码意义,绘制出自己想要的图!

大海哥还提供思路设计、定制生信分析、文献思路复现;有需要的小伙伴欢迎直接扫码咨询~

定制生信分析

服务器租赁

扫码咨询大海哥

往期回顾

01

生信人必备神器——1024G存储的生信服务器,免费试用啦

02

【BWMR】孟德尔随机化分析利器,克服分析挑战!

03

分子对接花了几个小时?批量分子对接帮你5分钟搞定!

04

手把手带你复现XGboost和LightGBM机器学习算法特征重要性排名和 SHAP 汇总图