热图如何展示特定行名,缩放单元格大小?

今天结合nature medicine中的一篇文章,和大家分享下热图的绘制,主要亮点功能是:
(1)名称太多看不清,如何只展示特定的名称?
(2)数据太密集,如何快速调整单元格的宽和高?

论文页面

image.png

文章链接https://www.nature.com/articles/s41591-020-0944-y

代码及数据https://github.com/ajwilk/2020_Wilk_COVID

拟复现图片样式:Fig2中的热图样式

图1 拟复现图片样式

代码实现

使用数据:数据大家可以通过上述链接下载,附件是一个rds文件(1.5G,一般电脑慎加载会卡死的), 基因云平台(https://www.genescloud.cn)已经整理了一个示例数据,可以在线选择使用。具体可参考下图7 云端数据选择。

图2 示例数据

按照惯例,我们先画一个基本的热图。

library(pheatmap)     
library(grid)    
mat <- read.delim("heatmap.txt",sep="\t",row.names=1)
pheatmap(mat)
图3 初始热图

上图样式不是很好看,存在以下几点需要完善:①颜色不是很好看,且有灰色边框线条;②行名有很多重叠无法识别;③ 热图缺少分组信息, 接下来我们通过代码继续完善。

# 设置颜色
color <- c("blue", "white", "red")
myColor <- colorRampPalette(color)(100)

# 添加分组信息
annotation_col <- data.frame(Group = factor(rep(c("T", "C"),4)))
rownames(annotation_col) <- colnames(mat)

# 绘制热图
p1 <- pheatmap(mat,color = myColor,
               border_color=NA, 
               annotation_col = annotation_col) 
图4 美化后热图一

接下来通过调整单元格高度,使得文字错开。

# 调整单元格高度,避免文字重叠
p1 <- pheatmap(mat,color = myColor,
               border_color=NA, 
               annotation_col = annotation_col,
               cellheight=10)
图5 美化后热图二

上图通过调整单元格高度调整,文字是清晰可分辨了,但是图片的整体高度会被拉长,放在文章里面不太方便查看。那么我们是否可以只展示特定的行名呢? 首先我们来看下文中提及的,可以实现只展示特定行名的函数:

# 展示特定行名函数
add.flag <- function(pheatmap,
                     kept.labels,
                     repel.degree) {

  heatmap <- pheatmap$gtable

  new.label <- heatmap$grobs[[which(heatmap$layout$name == "row_names")]] 

  # keep only labels in kept.labels, replace the rest with ""
  new.label$label <- ifelse(new.label$label %in% kept.labels, 
                            new.label$label, "")

  # calculate evenly spaced out y-axis positions
  repelled.y <- function(d, d.select, k = repel.degree){
    # d = vector of distances for labels
    # d.select = vector of T/F for which labels are significant

    # recursive function to get current label positions
    # (note the unit is "npc" for all components of each distance)
    strip.npc <- function(dd){
      if(!"unit.arithmetic" %in% class(dd)) {
        return(as.numeric(dd))
      }

      d1 <- strip.npc(dd$arg1)
      d2 <- strip.npc(dd$arg2)
      fn <- dd$fname
      return(lazyeval::lazy_eval(paste(d1, fn, d2)))
    }

    full.range <- sapply(seq_along(d), function(i) strip.npc(d[i]))
    selected.range <- sapply(seq_along(d[d.select]), function(i) strip.npc(d[d.select][i]))

    return(unit(seq(from = max(selected.range) + k*(max(full.range) - max(selected.range)),
                    to = min(selected.range) - k*(min(selected.range) - min(full.range)), 
                    length.out = sum(d.select)), 
                "npc"))
  }
  new.y.positions <- repelled.y(new.label$y,
                                d.select = new.label$label != "")
  new.flag <- segmentsGrob(x0 = new.label$x,
                           x1 = new.label$x + unit(0.15, "npc"),
                           y0 = new.label$y[new.label$label != ""],
                           y1 = new.y.positions)

  # shift position for selected labels
  new.label$x <- new.label$x + unit(0.2, "npc")
  new.label$y[new.label$label != ""] <- new.y.positions

  # add flag to heatmap
  heatmap <- gtable::gtable_add_grob(x = heatmap,
                                     grobs = new.flag,
                                     t = 4, 
                                     l = 4
  )

  # replace label positions in heatmap
  heatmap$grobs[[which(heatmap$layout$name == "row_names")]] <- new.label

  # plot result
  grid.newpage()
  grid.draw(heatmap)

  # return a copy of the heatmap invisibly
  invisible(heatmap)
}

函数写好了,接下来我们看看具体效果。本示例随机抽取20个行名,添加到原来的热图中。具提代码如下,最终效果图如图6所示。

# 这里随机抽取20个基因进行展示
gene_name<-sample(rownames(mat),20)
add.flag(p1,kept.labels = gene_name,repel.degree = 0.2)</pre>
图6 美化后热图三

到此我们就成功的通过代码实现了一幅含有分组信息,只展示特定行名的热图,那么如何不通过代码实现呢?接下来,给大家分享下基因云(https://www.genescloud.cn)的“交互热图”,帮助你“0”代码快速制作漂亮的上述图表,同时还提供多种样式的在线调整。

无代码实现

1 准备数据

为了方便大家学习实践,基因云平台已整合该文章数据,进入“交互热图”绘图页面,直接通过【文件上传→云端文件→公共数据】按照路径: Home>ref_data>COVID-19_data>交互热图,即可选择使用。

image
图7 云端数据选择

2 提交绘图

选择好数据和分组文件后,一键提交绘图。

图8 快速提交页面

3 参数调整

(1)显示特定基因名称:在图表调整里面,选择【显示名称→行/行列】,下方会出现所有行名列表,可随意勾选你想要展示的名称。

图9 显示特定基因名称

(2)随意伸缩单元格宽高:在图表调整栏,随意拖动【单元格宽度/高度】对应的滑动控制条,可随意更改热图单元格的宽和高。

图10 调整单元格长宽
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343

推荐阅读更多精彩内容