前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >R包:gtable包用于处理ggplot2图像

R包:gtable包用于处理ggplot2图像

作者头像
生信菜鸟团
发布2020-10-12 18:46:45
2.1K0
发布2020-10-12 18:46:45
举报
文章被收录于专栏:生信菜鸟团生信菜鸟团

ggplot2是基于grid的绘图工具,它绘制的图像其实是由多个grob(grid graph object)组成的,比如一张点图,它的标题是titleGrob,点图的基本单元包括pointsGrob。

gtable可以个性化修改定制这些grob对象,从而可以对gplot2绘图对象进行更加高阶的定制,比如拼图、图中嵌图等。

很多工具包都可以进行拼图或嵌图, 比如cowplot、patchwork、ggpubr、gridExtra等等,但是gtable是相对底层的进行操纵ggplot2对象的包。cowplot的很多功能实现就依赖于gtable。

最近探索了一下gtable的使用,主要是两个方面:如何进行拼图和嵌图。

使用gtable进行拼图

cowplot拼图示例

cowplot就可以很方便的进行拼图,使用plot_grid函数即可,如下图所示。

如果觉得每张图片太大,还可以使用scale功能对每张图片进行缩放。

对于ncol、nrow参数而言,它们几乎已经是拼图布局的行列定义的标签了,在多个拼图工具中都能见到,比如ggpubr的ggarrange函数,当然这也不奇怪,毕竟ggarrange就是依赖的cowplot包。

还可以定义多行或者多列的比例,使用rel_widths或者rel_heights来指定。

align参数用于对齐多个图的元素,可以对水平、垂直方向进行对齐。

代码语言:javascript
复制
library(tidyverse)
library(grid)
library(gtable)
library(cowplot)

p1 <- mtcars %>% ggplot(aes(x = mpg, y = disp, color = am)) + 
  geom_point()
p2 <- iris %>%  ggplot(aes(x = Sepal.Length, y = Sepal.Width)) +
  geom_boxplot(aes(fill = Species))
cowplot::plot_grid(p1, p2, ncol = 2)
gtable进行拼图

如果要使用gtable进行拼图,只需要创建一个1行2列的gtable对象,然后每个位置填入相应的图像即可。

填充图形是使用的gtable_add_grob实现的。

代码语言:javascript
复制
# 将待拼图转换为gtable对象(grob table)
# 以下两种方式都可以,函数来源于ggplot2
g1 <- ggplotGrob(p1)
g2 <- ggplot_gtable(ggplot_build(p2))

# 创建一个布局为一行两列的gtable对象,用于放置上述的两个对象
# 每一个位置的长宽都是1 null
fig_combined <- gtable(widths = unit(c(1, 1), "null"),
                       heights = unit(1, "null"))

# 将两张图片分别放入gtable中
# gtable_add_grob可以对gtable对象进行操纵,添加
# t是top,上边界是第一行
# l是left,左边界是第一列
fig_combined <- gtable_add_grob(fig_combined,
                grobs = g1,
                t = 1,
                l = 1)
# l是left,左边界是第二列
fig_combined <- gtable_add_grob(fig_combined,
                grobs = g2,
                t = 1,
                l = 2)
plot(fig_combined)

这个图像其实和cowplot的出图是一样的,就不附图了。

其实只需要简单修改就可以实现不同比例的拼图,比如让左右两图的宽度是2:1,那么只需要设置好新建gtable的宽度为2null和1null即可。如下图所示。

另外更有意思的是,新建gtable的宽度并非要求整数,gtable(widths = unit(c(1, 0.5), "null"), heights = unit(1, "null"))也是可以的。

代码语言:javascript
复制
# 创建一个一行两列的gtable对象,宽度分别是2null和1null
fig_combined <- gtable(widths = unit(c(2, 1), "null"),
                       heights = unit(1, "null"))
# 其他照旧
fig_combined <- gtable_add_grob(fig_combined,
                grobs = g1,
                t = 1,
                l = 1)
fig_combined <- gtable_add_grob(fig_combined,
                grobs = g2,
                t = 1,
                l = 2)
plot(fig_combined)

使用gtable进行嵌图

cowplot嵌图示例

cowplot进行嵌图的思路是通过创建新画布并不停叠加图层来实现,由于新图层的位置和大小可以调,也就呈现出了不同的嵌图效果。

比如将第二张图的宽和高设置为以前的30%,并且将其放在绘图区域的右上角(绘图区域(0.6,0.6)是待嵌图的左下角。)

这里的0.6是相当于整个绘图区域而言(下图灰色部分),而不是第一张图的坐标轴显示区域, 其值是相对值,最宽最高代表值为1。

代码语言:javascript
复制
ggdraw() +
  draw_plot(p1) + 
  draw_plot(p2, x = 0.6, y = 0.6, width = 0.3, height = 0.3)

cowplot还可以对其图表并进行叠加,思路也是一样的。

代码语言:javascript
复制
# 使用透明主题,以防止图片被覆盖
p2_new <- p2 + cowplot::theme_cowplot() 
# 对齐图片
align_grobs <- cowplot::align_plots(p1, p2_new, align = "h")
# 去除坐标轴和图例
align_grobs[[2]] <- cowplot::gtable_remove_grobs(
    align_grobs[[2]], 
    names = c("axis-b", "axis-l",
              "xlab-b", "ylab-l", "guide-box") )
# 拼图
ggdraw() +
  draw_grob(align_grobs[[1]]) + 
  draw_grob(align_grobs[[2]]) 
gtable进行嵌图

gtable也可以进行嵌图,思路和拼图是一样的,先构造一个新gtable布局,然后将图片依次嵌入。

不同于cowplot嵌图,在这里可以指定图片只嵌到坐标轴指示的panel区域。让嵌入的图是主图的panel区域的40%大小。

代码语言:javascript
复制
# p2添加边框,以用于嵌图显示,并转换为gtable对象:g2_new
g2_new <- ( p2 + theme(plot.background = element_rect(fill = NA, colour = "black")) ) %>% cowplot::as_gtable()

# 取出g1的panel区域及panel区域的位置信息(layout)
g1_panel <- gtable::gtable_filter(g1, "panel")
g1_panel_layout <- g1 %>% .$layout %>% filter(name == "panel") %>% c()

# 将g2_new按照比例并到g1的panel
# 新建panel是2*2的绘图方格,比例都是6:4
# g1_panel占据新建的gtable全部方格,而g2_new只在右上方方格
# 于是g2_new就是g1_panel的40%大小
fig_embed <- gtable(widths = unit(c(0.6, 0.4), "null"), 
                    heights = unit(c(0.4, 0.6), "null"))
fig_embed <- gtable_add_grob(fig_embed, g1_panel,
                             t=1,l=1,b=2,r=2)
fig_embed <- gtable_add_grob(fig_embed, g2_new,
                             t=1,l=2)

# 将合并好的fig_embed重新覆盖g1的panel区域
fig_embed <- gtable_add_grob(g1, fig_embed,
                             t = g1_panel_layout$t,
                             l = g1_panel_layout$l,
                             b = g1_panel_layout$b,
                             r = g1_panel_layout$r)
plot(fig_embed)

还可以通过对p2添加空白框,从而完成图形的缩放:

代码语言:javascript
复制
# 添加空白区域,缩放为90%大小
g2_scale <- gtable_add_padding(g2_new, padding = unit(0.05, "npc"))

# 以下是相同的操作
# 取出g1的panel和panel的位置信息
g1_panel <- gtable::gtable_filter(g1, "panel")
g1_panel_layout <- g1 %>% .$layout %>% filter(name == "panel") %>% c()

# 将g2并到g1的panel
fig_embed <- gtable(widths = unit(c(0.6, 0.4), "null"), 
                    heights = unit(c(0.4, 0.6), "null"))
fig_embed <- gtable_add_grob(fig_embed, g1_panel,
                             t=1,l=1,b=2,r=2)
fig_embed <- gtable_add_grob(fig_embed, g2_scale,
                             t=1,l=2)

# 将合并好的fig_embed重新覆盖g1的panel区域
fig_embed <- gtable_add_grob(g1, fig_embed,
                             t = g1_panel_layout$t,
                             l = g1_panel_layout$l,
                             b = g1_panel_layout$b,
                             r = g1_panel_layout$r)
plot(fig_embed)
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-09-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 生信菜鸟团 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 使用gtable进行拼图
    • cowplot拼图示例
      • gtable进行拼图
      • 使用gtable进行嵌图
        • cowplot嵌图示例
          • gtable进行嵌图
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档