R 数据可视化 —— ggplot 色块图

前言

绘制色块图的函数有三个,其中 geom_rect()geom_tile() 除了参数不同之外,其他都是一样的。

  • geom_rect 使用四个角参数:xmin, xmax, ymin and ymax
  • geom_tile 指定了中心位置和大小参数:x, y, width, height

geom_raster 是条块大小相同时 geom_tile 的快速版本,而且当输出为 PDF 时所占空间也更小

示例

绘制简单的热图

ggplot(faithfuld, aes(waiting, eruptions)) +
 geom_raster(aes(fill = density))

增加图像的平滑度

ggplot(faithfuld, aes(waiting, eruptions)) +
 geom_raster(aes(fill = density), interpolate = TRUE)

如果想要绘制矩形块,可以使用 geom_tile()

df <- data.frame(
  x = rep(c(2, 5, 7, 9, 12), 2),
  y = rep(c(1, 2), each = 5),
  z = factor(rep(1:5, each = 2)),
  w = rep(diff(c(0, 4, 6, 8, 10, 14)), 2)
)
ggplot(df, aes(x, y)) +
  geom_tile(aes(fill = z), colour = "grey50")
ggplot(df, aes(x, y, width = w)) +
  geom_tile(aes(fill = z), colour = "grey50")

geom_rect()

ggplot(df, aes(xmin = x - w / 2, xmax = x + w / 2, ymin = y, ymax = y + 1)) +
  geom_rect(aes(fill = z), colour = "grey50")

极坐标化

p1 <- ggplot(df, aes(x, y, width = w)) +
  geom_tile(aes(fill = z), colour = "grey50") +
  coord_polar(theta = 'x')

p2 <- ggplot(df, aes(x, y, width = w)) +
  geom_tile(aes(fill = z), colour = "grey50") +
  coord_polar(theta = 'y')

plot_grid(p1, p2)

样式

1. 华夫饼图

华夫饼图包括两种类型:

  1. 块状华夫饼图:

用于展示每组数据占总体的比例情况,可以快速看出数据中不同类别的分布以及占比,同时也可以知道不同分组之间的分布差异

其中堆积型侧重于展示类别数值

df <- tibble(
  x = rep(1:10, 10),
  y = rep(1:10, each=10),
  class = sort(sample(mpg$class, 100))
)

sample_n(df, 67) %>% 
  arrange(x, y) %>% 
  group_by(x) %>% 
  mutate(y = 1:n()) %>%
  ggplot(aes(x, y, fill = class)) +
  geom_tile(colour = "white") +
  # geom_point(size = 12, shape = 21) +
  coord_fixed() +
  theme(panel.background = element_blank(),
        axis.title = element_blank(),
        axis.text = element_blank(),
        axis.ticks = element_blank())

以及侧重于展示类别占比的百分比堆积型

ggplot(df, aes(x, y, fill = class)) +
  geom_tile(colour = "white") +
  scale_y_continuous(trans = "reverse") +
  theme(panel.background = element_blank(),
        axis.title = element_blank(),
        axis.text = element_blank(),
        axis.ticks = element_blank())
  1. 点状华夫饼图:

以点图矩阵的方式展示离散数据,用颜色来区分不同组别。功能与块状华夫饼图相同

ggplot(df, aes(x, y, fill = class)) +
  # geom_tile(colour = "white") +
  geom_point(size = 12, shape = 21) +
  coord_fixed() +
  scale_y_continuous(trans = "reverse") +
  theme(panel.background = element_blank())

2. 马赛克图

马赛克图用于显示分类数据中一对变量之间的关系。

df <- tibble(
  gene = rep(LETTERS[1:5], 4),
  status = rep(c("alpha", "beta", "gamma", "delta"), each = 5),
  value = sample(1:100, 20),
  percent = rep(c(10, 30, 30, 20, 10), 4)
)

df %>% 
  group_by(status) %>%
  mutate(xmax = cumsum(percent), xmin = xmax - percent) %>%
  group_by(gene) %>% 
  mutate(ytmp = value * 100 / sum(value), ymax = cumsum(ytmp), ymin = ymax - ytmp) %>%
  mutate(x = (xmin + xmax) / 2, y = (ymin + ymax) / 2) %>%
  ggplot() + 
  geom_rect(aes(xmin = xmin, ymin = ymin, xmax = xmax, ymax = ymax, fill = status),
            colour = "black") +
  geom_text(aes(x, y, label = paste0(round(ytmp, 2), "%"))) +
  geom_text(aes(x = x, y = 103, label = gene)) +
  theme(panel.background = element_blank())
马赛克图

3. 瀑布图

假设我们有如下突变数据

> data
# A tibble: 2,432 x 3
   sample   gene  MutFunc          
   <chr>    <chr> <chr>            
 1 C1803704 ATM   nonsynonymous SNV
 2 C1803704 BRAF  nonsynonymous SNV
 3 C1803704 BRCA1 synonymous SNV   
 4 C1803704 BRCA1 nonsynonymous SNV
 5 C1803704 BRCA2 nonsynonymous SNV
 6 C1803704 BRCA2 synonymous SNV   
 7 C1803704 BRCA2 stopgain         
 8 C1803704 BRD4  nonsynonymous SNV
 9 C1803704 EOMES nonsynonymous SNV
10 C1803704 EPCAM nonsynonymous SNV
# … with 2,422 more rows

我们需要绘制基因在样本中的突变情况和每个样本的突变基因数情况,以及每个基因在样本中的突变情况,三个图结合在一起。

颜色表示不同的突变类型。

首先,对数据进行处理,

data <- df %>% select(sample, gene, MutFunc) %>%
  distinct() %>%
  filter(MutFunc != ".")

genes <- count(data, gene) %>%
  top_n(n = 20, wt = n) %>%
  mutate(percent = round(n * 100 / sum(n), 1)) %>%
  arrange(desc(n))
  
samples <- subset(data, gene %in% genes$gene) %>%
  count(sample) %>% arrange(desc(n)) %>%
  rename(num = n)

df <- inner_join(data, genes) %>%
  mutate(gene = factor(gene, levels = rev(genes$gene)),
         sample = factor(sample, levels = samples$sample)) %>%
  inner_join(samples)

转换为这个格式的数据

> df
# A tibble: 978 x 6
   sample   gene   MutFunc               n percent   num
   <chr>    <fct>  <chr>             <int>   <dbl> <int>
 1 C1803704 ATM    nonsynonymous SNV    16     1.6    16
 2 C1803704 BRCA1  synonymous SNV      137    14      16
 3 C1803704 BRCA1  nonsynonymous SNV   137    14      16
 4 C1803704 BRCA2  nonsynonymous SNV   274    28      16
 5 C1803704 BRCA2  synonymous SNV      274    28      16
 6 C1803704 BRCA2  stopgain            274    28      16
 7 C1803704 EOMES  nonsynonymous SNV    31     3.2    16
 8 C1803704 PIK3CA nonsynonymous SNV    39     4      16
 9 C1803704 TP53   stopgain             55     5.6    16
10 C1803710 BRCA1  synonymous SNV      137    14      11
# … with 968 more rows

然后绘制这三张图

p1 <- ggplot(df) +
  geom_tile(aes(x = sample, y = gene, fill = MutFunc)) +
  # geom_text(aes(x = -4, y = gene, label = percent), data = genes) +
  # 图例行数的调整放到 fill,单独用 guides 无效
  scale_fill_discrete(guide = guide_legend(nrow = 3)) +
  scale_y_discrete(position = "right") +
  theme(axis.text.x = element_blank(),
        axis.text.y.left = element_text(size = 4),
        axis.ticks = element_blank(),
        axis.title = element_blank(),
        legend.position = "bottom",
        legend.background = element_rect(fill = 'white', colour = 'black')
        )
# 样本的突变基因数目条形图
p2 <- ggplot(df) +
  geom_bar(aes(x = sample, fill = MutFunc)) +
  # 使用 expand 删除数据与轴之间的空隙
  scale_y_continuous(breaks = seq(0, 25, 5), limits = c(0, 25), 
                     expand = expansion(mult = 0, add = 0)) +
  theme(
    legend.position = "none",
    panel.background = element_blank(),
    axis.title = element_blank(),
    axis.ticks.x = element_blank(),
    axis.title.x = element_blank(),
    axis.text.x = element_blank(),
    axis.ticks.length.y.left = unit(.25, "cm"),
    axis.line.y.left = element_line(colour = "black"),
  )
# 突变基因的突变频数条形图
p3 <- ggplot(df) +
  geom_bar(aes(y = gene, fill = MutFunc)) +
  scale_x_continuous(position = "top", breaks = seq(0, 280, 70),
                     limits = c(0, 280),
                     expand = expansion(mult = 0, add = 0)) +
  theme(
    legend.position = "none",
    panel.background = element_blank(),
    axis.title = element_blank(),
    axis.ticks.y = element_blank(),
    axis.title.y = element_blank(),
    axis.text.y = element_blank(),
    axis.ticks.length.x.top = unit(.25, "cm"),
    axis.line.x.top = element_line(colour = "black")
  )

最好将三张图拼接起来

p12 <- plot_grid(p2, p1, nrow = 2, align = "v",
          rel_heights = c(1, 5))

pr <- plot_grid(NULL, p3, NULL, nrow = 3, align = "v",
                rel_heights = c(0.95, 5, 1.05))

plot_grid(p12, pr, ncol = 2, align = "h",
          rel_widths = c(5, 1))
瀑布图

代码:https://github.com/dxsbiocc/learn/tree/main/R/plot/color_block.R

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

推荐阅读更多精彩内容