美文网首页R plotIMP research
9.ggplot2——图形排列

9.ggplot2——图形排列

作者: denghb001 | 来源:发表于2021-11-25 07:29 被阅读0次

9 图形排列

ggplot2 中提供的语法与创建单个图有关。虽然分面系统提供了生成多个子图的方法,但所有这些都主要都是可视化、共享层、数据和比例的一部分。然而,通常需要使用多个不同的图形来讲述一个故事或提出一个论点。这些当然可以单独创建并在布局程序中组装,但在代码中执行此操作是有益的,以避免耗时且不可重复的工作。一系列的方案应运而生,提供了安排不同图形的不同方法。虽然本章将重点介绍 patchwork 包,但您也可以在 cowplot、gridExtra 和 ggpubr 包中找到一些相同的功能。

本章将分为两部分。第一种方法是将图形块并排排列而不重叠,而第二种方法是将图形块依次排列。虽然这两种方案不一定是相互对立的,但前一种情况通常会受益于后一种情况下没有意义的功能,例如绘图区域的对齐。

9.1 图形并排

通常,人们希望并排展示两个或更多图形,从不同方面展示同一故事。这是拼凑而成的场景来解决。从本质上讲,patchwork 是一个包,它对ggplot2扩展了 +操作符的使用以在多个图之间工作,并为专门的组合添加额外的操作符和处理图的组合。

作为patchwork最基本用法的示例,我们将使用mpg数据集的以下4个图

p1 <- ggplot(mpg) + 
  geom_point(aes(x = displ, y = hwy))

p2 <- ggplot(mpg) + 
  geom_bar(aes(x = as.character(year), fill = drv), position = "dodge") + 
  labs(x = "year")

p3 <- ggplot(mpg) + 
  geom_density(aes(x = hwy, fill = drv), colour = NA) + 
  facet_grid(rows = vars(drv))

p4 <- ggplot(mpg) + 
  stat_summary(aes(x = drv, y = hwy, fill = drv), geom = "col", fun.data = mean_se) +
  stat_summary(aes(x = drv, y = hwy), geom = "errorbar", fun.data = mean_se, width = 0.5)

拼凑最简单的用法是+将绘图添加到一起,从而创建一组要显示在一起的绘图:

library(patchwork)

p1 + p2
image.png

+没有指定任何特定的布局,只是应该将图一起显示。在没有布局的情况下,控制facet_wrap()中行数和列数的相同算法将决定行数和列数。这意味着将 3 个图加在一起将创建一个 1x3 网格,而将 4 个图加在一起将创建一个 2x2 网格。

p1 + p2 + p3 + p4
image.png

从上面的两个例子可以看出,patchwork 负责将图的不同部分相互对齐。您可以看到所有绘图区域都是对齐的,即使存在分面也是如此。此外,您可以看到尽管左下图中的轴文本更宽,但最左侧的两个图中的 y 轴标题已对齐。

9.1.1 布局控制

通常自动创建的网格不是您想要的,当然可以控制它。最直接、最强大的方法是在``plot`中添加一个plot_layout()规范:

p1 + p2 + p3 + plot_layout(ncol = 2)
image.png

一个常见的场景是想要强制单行或单列。拼缝提供了两个操作员,/|分别以促进此(引擎盖下他们只是组的行或列中的布局编号为1)。
一种常见的场景是希望强制执行单个行或列。Patchwork分别提供了两个操作符/|来实现这一点(实际上它们只是将布局中的行数或列数设置为1)。

p1 / p2
image.png
# Basically the same as using `+` but the intend is clearer
p3 | p4
image

patchwork 允许布局嵌套,这意味着仅使用这两个运算符就可以生成一些非常复杂的布局

p3 | (p2 / (p1 | p4))
image

另外,对于非常复杂的布局,也可以在plot_layout()design参数中使用文本表示来指定非表格布局。

layout <- "
AAB
C#B
CDD
"

p1 + p2 + p3 + p4 + plot_layout(design = layout)
image

正如在最后几幅图中显示的那样,图形之间的图例就变得多余。虽然可以在组装之前删除某个图中的所有图例之外的所有图例,但patckwork为常见情况提供了一些更容易的方法:

p1 + p2 + p3 + plot_layout(ncol = 2, guides = "collect")
image.png

选择收集guides将把所有图例放在一起,放在全局主题所支配的位置。此外,它将删除任何重复的图例,只在图形中留下唯一的图例。重复检测图例的外观,而不是它来自的底层比例。因此,它只会删除完全相同的图例。如果您想通过将参考线放置在布局的空白区域来优化空间使用,您可以为收集的参考线指定一个绘图区域:

p1 + p2 + p3 + guide_area() + plot_layout(ncol = 2, guides = "collect")
image.png

9.1.2 修改子图

patchwork执行规则是:在渲染之前,绘图保持为标准的 ggplot 对象。这意味着它们在组装后可以进行修改。可以通过[[]]索引检索和设置特定图:

p12 <- p1 + p2
p12[[2]] <- p12[[2]] + theme_light()
p12
image.png

但是,通常有必要一次修改所有子图,例如给它们一个共同的主题。patchwork提供了的&适用于该处:

p1 + p4 & theme_minimal()
image.png

如果它们在该轴上具有相同的图形属性,这也可用于为绘图提供一个公共轴:

p1 + p4 & scale_y_continuous(limits = c(0, 45))
image.png

9.1.3 添加注释

图形一旦被组装起来,它们就开始形成一个整体。这也意味着标题、副标题和说明文字通常与整个图形有关,而不再是其中的某一个图形。可以使用该plot_annotation()函数将标题等添加到组装的图中。

p34 <- p3 + p4 + plot_annotation(
  title = "A closer look at the effect of drive train in cars",
  caption = "Source: mpg dataset in ggplot2"
)
p34
image.png

根据调用plot_annotation()中的主题规范格式化标题。

p34 + plot_annotation(theme = theme_gray(base_family = "mono"))
image

由于全局主题通常跟随子图形的主题,&与主题对象一起使用将修改全局主题以及子图形的主题

p34 & theme_gray(base_family = "mono")
image.png

另一种类型的注释,特别是在文献中,是向每个子图添加标签,然后用于在文本和标题中识别它们。ggplot2 正好有这个tag元素,patchwork 提供了使用tag_levels参数自动设置它的功能。它可以自动生成拉丁字符、阿拉伯数字或罗马数字。

p123 <- p1 | (p2 / p3)
p123 + plot_annotation(tag_levels = "I") # Uppercase roman numerics
image

一个附加功能是可以使用嵌套来定义新的标记级别:

p123[[2]] <- p123[[2]] + plot_layout(tag_level = "new")
p123 + plot_annotation(tag_levels = c("I", "a"))
image.png

可以看出,patchwork可以生成不同的图形排布,并且 API 会随着组件的复杂程度而扩展,从简单+地将多个绘图放置在同一区域,到使用嵌套、布局、和注释以创建高级自定义布局。

9.2 在图形上排列图

虽然 patchwork 中的许多功能都与对齐网格中的图有关,但它也允许您制作插图,即放置在另一个图上的小图。此功能包含在inset_element()函数中,该函数用于将给定的绘图标记为要放置在前一个绘图上的插图,并记录所需的位置等。基本用法如下:

p1 + inset_element(p2, left = 0.5, bottom = 0.4, right = 0.9, top = 0.95)
image.png

实际位置由给定插图的左侧、右侧、顶部和底部位置指定。默认值是npc,在给定区域中使用从 0 到 1 的单位,但grid::unit()可以明确给出它们来使用任何单位。该位置默认设置为面板区域,但这可以通过align_to参数进行更改。结合这些知识点,我们可以在距右上角 15 毫米处放置一个插图,如下所示:

p1 + 
  inset_element(
    p2, 
    left = 0.4, 
    bottom = 0.4, 
    right = unit(1, "npc") - unit(15, "mm"), 
    top = unit(1, "npc") - unit(15, "mm"),
    align_to = "full"
  )
image.png

插图不限于 ggplots。wrap_elements()可以使用任何支持的图形,包括patchwork拼凑图:

p24 <- p2 / p4 + plot_layout(guides = "collect")
p1 + inset_element(p24, left = 0.5, bottom = 0.05, right = 0.95, top = 0.9)
image

插图的一个很好的特点是它们在被渲染之前表现为标准的拼凑子图。这意味着它们可以在组装后进行修改,通过使用&

p12 <- p1 + inset_element(p2, left = 0.5, bottom = 0.5, right = 0.9, top = 0.95)
p12 & theme_bw()
image

自动标记也按预期工作:

p12 + plot_annotation(tag_levels = 'A')
image

9.3 总结

本章简要概述了 patchwork 提供的一些组合可能性。Patchwork 不仅支持 ggplots,还允许您在需要时将网格和基本图形元素与您的绘图结合起来。它还允许使用area()构造函数,而不仅仅是此处展示的文本表示进行更复杂的设计。所有这些功能以及更多功能都包含在其网站上的不同指南中: https://patchwork.data-imaginist.com

相关文章

网友评论

    本文标题:9.ggplot2——图形排列

    本文链接:https://www.haomeiwen.com/subject/tciwtrtx.html