查看原文
其他

保姆级:手把手教你绘制环形基因表达热图

JunJunLab 老俊俊的生信笔记 2022-08-15


点击上方关注我们






发生




之前也没画过环形的热图,自己在绘制时也会遇到很多坑,之前看过 小明哥 的教程,昨天请教了一下 小明哥 ,他也非常耐心仔细地指导了一下,在此非常感谢,哈哈。

下面是他的公众号,非常的优秀!估计大家大部分都已经关注了吧。

这是万恶之源:

TBtoolscirclize 同样也可以绘制,后面有时间介绍, TBtools 是一个神器,里面集合了各种各样地生信分析软件,无需代码编程能力即可完成分析。

下面进入主题,绘制基因表达量热图。

1、尝试


加载数据:

# 加载R包
library(tidyverse)

# 设置工作路径
setwd('C:\\Users\\admin\\Desktop')

# 读取数据
da <- read.table('tt.txt',header = T)

# 查看数据
head(da,3)

  gene_name          s1         s2        s3
1     KHDC4  0.19644441 -0.1719071  4.395833
2     DCAF1 -0.06520404 -3.7762904  0.678249
3    CAB39L  0.59622658 -0.2124622 -1.810885

第一列是 基因名,后面三列对应 3 个样本基因地表达量,我用的是 log2FC

先挑一个样本尝试:

# 宽数据转长数据
cirp <- melt(da)

# 查看数据
head(cirp,3)
  gene_name variable       value
1     KHDC4       s1  0.19644441
2     DCAF1       s1 -0.06520404
3    CAB39L       s1  0.59622658

# 画一个样本
res <- cirp %>% filter(variable == 's1')

# 绘图
ggplot(res,aes(x = as.numeric(rownames(res)),y = 1)) +
  geom_tile(aes(fill = value),color = 'black')

我们可以调一下颜色:

# 设置颜色
ggplot(res,aes(x = as.numeric(rownames(res)),y = 1)) +
  geom_tile(aes(fill = value),color = 'black') +
  scale_fill_gradient2(midpoint = 0,
                       low = '#3C8DAD',
                       mid="white",
                       high = '#FF6767')

然后转换坐标系为极坐标系,掰弯它!

# 坐标系转换,转为极坐标
ggplot(res,aes(x = as.numeric(rownames(res)),y = 1)) +
  geom_tile(aes(fill = value),color = 'black') +
  scale_fill_gradient2(midpoint = 0,
                       low = '#3C8DAD',
                       mid="white",
                       high = '#FF6767') +
  coord_polar(theta = 'x')

主题优化简洁一下:

# 主题优化
ggplot(res,aes(x = as.numeric(rownames(res)),y = 1)) +
  geom_tile(aes(fill = value),color = 'black') +
  scale_fill_gradient2(midpoint = 0,
                       low = '#3C8DAD',
                       mid="white",
                       high = '#FF6767') +
  coord_polar(theta = 'x') +
  theme_void()

这个地方有个需要注意地点,如何把中间空出来,关键点在于设置 Y 轴地范围

# 拓展Y坐标轴
ggplot(res,aes(x = as.numeric(rownames(res)),y = 1)) +
  geom_tile(aes(fill = value),color = 'black') +
  scale_fill_gradient2(midpoint = 0,
                       low = '#3C8DAD',
                       mid="white",
                       high = '#FF6767') +
  ylim(-2,2)

这里通过调整 ylim 范围 控制 环的 宽度大小

# 再次绘制
ggplot(res,aes(x = as.numeric(rownames(res)),y = 1)) +
  geom_tile(aes(fill = value),color = 'black') +
  scale_fill_gradient2(midpoint = 0,
                       low = '#3C8DAD',
                       mid="white",
                       high = '#FF6767') +
  ylim(-2,2) +
  coord_polar(theta = 'x') +
  theme_void()

这里我们通过控制 xlim 可以调整 环的开口大小

# 调整开口
ggplot(res,aes(x = as.numeric(rownames(res)),y = 1)) +
  geom_tile(aes(fill = value),color = 'black') +
  scale_fill_gradient2(midpoint = 0,
                       low = '#3C8DAD',
                       mid="white",
                       high = '#FF6767') +
  ylim(-2,2) + xlim(0,105) +
  coord_polar(theta = 'x') +
  theme_void()

2、添加基因名标签


为了更好展示 基因名对应表达量矩形相对角度 ,我们可以计算每个标签的角度朝向,来更好的展示基因名的可读性:

# 添加文字标签

# 计算角度
res$ang <- seq(from = (360/nrow(res)) / 1.5,
               to = (1.5* (360/nrow(res))) - 360,
               length.out = nrow(res)) + 80

# 根据角度确定朝向的方向
res$hjust <- 0
res$hjust[which(res$ang < -90)] <- 1
res$ang[which(res$ang < -90)] <- (180+res$ang)[which(res$ang < -90)]

# 查看结果
head(res,3)

  gene_name variable       value      ang hjust
1     KHDC4       s1  0.19644441 82.40000     0
2     DCAF1       s1 -0.06520404 78.79394     0
3    CAB39L       s1  0.59622658 75.18788     0

我们可以看到,每个基因名都要朝向和角度信息了,然后绘图看看,顺便把 图例放到中心 试试。

无开口:

# 无开口
ggplot(res,aes(x = as.numeric(rownames(res)),y = 1)) +
  geom_tile(aes(fill = value),color = 'black') +
  scale_fill_gradient2(midpoint = 0,
                       low = '#3C8DAD',
                       mid="white",
                       high = '#FF6767') +
  ylim(-2,2) +
  coord_polar(theta = 'x') +
  theme_void() +
  theme(legend.position = c(0.5,0.5)) +
  geom_text(data = res,
            aes(x = as.numeric(rownames(res)),
                y = 1.6,
                label = gene_name, angle = ang, hjust = hjust),
            size = 4)

有开口:

# 有开口
ggplot(res,aes(x = as.numeric(rownames(res)),y = 1)) +
  geom_tile(aes(fill = value),color = 'black') +
  scale_fill_gradient2(midpoint = 0,
                       low = '#3C8DAD',
                       mid="white",
                       high = '#FF6767') +
  ylim(-2,2) + xlim(0,105) +
  coord_polar(theta = 'x') +
  theme_void() +
  theme(legend.position = c(0.5,0.5)) +
  geom_text(data = res,
            aes(x = as.numeric(rownames(res)),
                y = 1.6,
                label = gene_name, angle = ang, hjust = hjust),
            size = 4)

3、多样本组合绘制


以上我们只是绘制一个样本的环形热图,我们可以通过 添加图层 的方式,将多个样本一起绘制出来:

# 多样本组合

library(ggnewscale)

p <- ggplot() +
  # 添加第一个环s1
  geom_tile(data = cirp[which(cirp$variable == 's1'),],
            aes(x = 1:100,y = 1,fill = value),
            color = 'black') +
  scale_fill_gradient2(midpoint = 0,
                       low = '#3C8DAD',
                       mid = "white",
                       high = '#FF6767',
                       name = 'ONE') +
  # 添加第一个环s2
  # 新增图例
  new_scale("fill") +
  geom_tile(data = cirp[which(cirp$variable == 's2'),],
            aes(x = 1:100,y = 2,fill = value),
            color = 'white') +
  scale_fill_gradient2(midpoint = 0,
                       low = '#A5E1AD',
                       mid = "white",
                       high = '#F55C47',
                       name = 'TWO') +
  # 添加第一个环s3
  # 新增图例
  new_scale("fill") +
  geom_tile(data = cirp[which(cirp$variable == 's3'),],
            aes(x = 1:100,y = 3,fill = value),
            color = 'black') +
  scale_fill_gradient2(midpoint = 0,
                       low = '#DA9FF9',
                       mid = "white",
                       high = '#FF9292',
                       name = 'THREE') +
  ylim(-2,4) +
  coord_polar(theta = 'x') +
  theme_void()
p

最后加上标签,直接用 s1 的就行:

# 添加基因名标签
p + geom_text(data = res,
              aes(x = as.numeric(rownames(res)),
                  # 关键参数,调整位置
                  y = 3.6,
                  label = gene_name, angle = ang, hjust = hjust),
              size = 4)

开口的试一下:

# 开口
p + geom_text(data = res,
              aes(x = as.numeric(rownames(res)),
                  y = 3.6,
                  label = gene_name, angle = ang, hjust = hjust),
              size = 4) +
  xlim(0,105)

给基因名加个颜色:

# 给标签添加颜色
p + geom_text(data = res,
              aes(x = as.numeric(rownames(res)),
                  y = 3.6,
                  label = gene_name, angle = ang, hjust = hjust),
              color = rainbow(100),
              size = 4) +
  xlim(0,105)

4、多样本映射绘图


出来叠加图层的方式,我们还可以以 映射 的方式绘制多样本的环形热图。

我们之前为了方便改变 Y轴X轴 范围,特意把 XY 轴变为数值型变量, 每个样本有 100 个基因,我们在长数据后面增加一列:

# 添加Y轴数值
cirp$var <- rep(1:100,3)

# 查看
head(cirp,3)

  gene_name variable       value var
1     KHDC4       s1  0.19644441   1
2     DCAF1       s1 -0.06520404   2
3    CAB39L       s1  0.59622658   3

绘图:

# 笛卡尔坐标系图
ggplot(cirp,aes(x = var,y = variable)) +
  geom_tile(aes(fill = value),color = 'black') +
  scale_fill_gradient2(midpoint = 0,
                       low = '#3C8DAD',
                       mid="white",
                       high = '#FF6767')

使用 scale_y_discrete 函数拓展 Y 轴

# 拓展Y轴
ggplot(cirp,aes(x = var,y = variable)) +
  geom_tile(aes(fill = value),color = 'black') +
  scale_fill_gradient2(midpoint = 0,
                       low = '#3C8DAD',
                       mid="white",
                       high = '#FF6767') +
  scale_y_discrete(expand = expansion(mult = c(2,0)))

最终成图:

# 成品图
p <- ggplot(cirp,aes(x = var,y = variable)) +
  geom_tile(aes(fill = value),color = 'black') +
  scale_fill_gradient2(midpoint = 0,
                       low = '#3C8DAD',
                       mid="white",
                       high = '#FF6767') +
  scale_y_discrete(expand = expansion(mult = c(2,0))) +
  coord_polar(theta = 'x') +
  theme_void() +
  geom_text(data = res,
            aes(x = as.numeric(rownames(res)),
                y = 3.6,
                label = gene_name, angle = ang, hjust = hjust),
            size = 4)
p

对于开口的话,调整一下 X 轴的范围即可:

# 开口
p + xlim(0,103) +
  theme(legend.position = c(0.5,0.5))

我们 X轴 也可以设置为基因名,使用scale_x_discrete 函数拓展 X 轴

# X、Y轴为分类变量
ggplot(cirp,aes(x = gene_name,y = variable)) +
  geom_tile(aes(fill = value),color = 'white') +
  scale_fill_gradient2(midpoint = 0,
                       low = '#3C8DAD',
                       mid="white",
                       high = '#FF6767') +
  scale_y_discrete(expand = expansion(mult = c(2,0))) +
  scale_x_discrete(expand = expansion(mult = c(0,0.05))) +
  coord_polar(theta = 'x') +
  theme_void() +
  geom_text(data = res,
            aes(x = as.numeric(rownames(res)),
                y = 3.6,
                label = gene_name, angle = ang, hjust = hjust),
            size = 4)

5、聚类


此外还可以对基因聚类,首先对原始数据的基因聚类获得聚类数据:

# 基因聚类
dac <- da[,-1]
rownames(dac) <- da$gene_name

# 聚类
xclust <- hclust(dist(dac))

然后绘制聚类环形热图:

# 加载包
library(ggh4x)
library(ggdendro)

# 开口型
ggplot(cirp,aes(x = gene_name,y = variable)) +
  geom_tile(aes(fill = value),color = 'white') +
  # 关键函数,聚类作用
  scale_x_dendrogram(hclust = xclust,
                     expand = expansion(mult = c(0,0.05))) +
  scale_fill_gradient2(midpoint = 0,
                       low = '#3C8DAD',
                       mid="white",
                       high = '#FF6767') +
  scale_y_discrete(expand = expansion(mult = c(2,0))) +
  theme(axis.text.x = element_blank()) +
  coord_polar(theta = 'x') +
  theme_void() +
  geom_text(data = res,
            aes(x = as.numeric(rownames(res)),
                y = 3.6,
                label = gene_name, angle = ang, hjust = hjust),
            size = 4)

封闭型:

# 封闭型
ggplot(cirp,aes(x = gene_name,y = variable)) +
  geom_tile(aes(fill = value),color = 'white') +
  # 关键函数,聚类作用
  scale_x_dendrogram(hclust = xclust) +
  scale_fill_gradient2(midpoint = 0,
                       low = '#3C8DAD',
                       mid="white",
                       high = '#FF6767') +
  scale_y_discrete(expand = expansion(mult = c(2,0))) +
  theme(axis.text.x = element_blank()) +
  coord_polar(theta = 'x') +
  theme_void() +
  geom_text(data = res,
            aes(x = as.numeric(rownames(res)),
                y = 3.8,
                label = gene_name, angle = ang, hjust = hjust),
            size = 3.5)

正常热图


最后我们绘制一个正常热图,用 ggplot

# 正常热图
# 基因聚类
dac <- da[,-1]
rownames(dac) <- da$gene_name

# 聚类
yclust <- hclust(dist(dac))
xclust <- hclust(dist(t(dac)))

# 绘图
ggplot(cirp,aes(x = variable,y = gene_name)) +
  geom_tile(aes(fill = value),color = 'white') +
  scale_fill_gradient2(midpoint = 0,
                       low = '#3C8DAD',
                       mid="white",
                       high = '#FF6767') +
  scale_y_dendrogram(hclust = yclust) +
  scale_x_dendrogram(hclust = xclust,position = 'top') +
  theme_classic() +
  xlab('') + ylab('')



你们学到了吗?



代码 我上传到 QQ 群 老俊俊生信交流群 文件夹里。欢迎加入。加我微信我也拉你进 微信群聊 老俊俊生信交流群 哦。

群二维码:


老俊俊微信:



所以今天你学习了吗?

欢迎小伙伴留言评论!

今天的分享就到这里了,敬请期待下一篇!

最后欢迎大家分享转发,您的点赞是对我的鼓励肯定

如果觉得对您帮助很大,赏杯快乐水喝喝吧!

推 荐 阅 读




您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存