使用 patchwork 来注释在不同位置具有标签的图

use*_*473 3 r ggplot2 patchwork

我使用 patchwork 来组装用 ggplot2 制作的图。我还使用 patchwork 的plot_annotation()命令自动注释组装好的图\xe2\x80\x94,例如自动将“A”、“B”等放置在每个图的右上角。在大多数情况下,这很容易做到。但是,当绘图的轴标签位于不同位置时,很难在正确的位置获得注释。这是问题的最小说明:

\n
library(ggplot2)\nlibrary(patchwork)\n\npLeft <- ggplot(mtcars) + \n  geom_point(aes(mpg, disp)) + \n  scale_y_continuous("Left-hand panel", position = "left")\n\npRight <- pLeft + \n  scale_y_continuous("Right-hand panel", position = "right")\n\npLeft + pRight + \n  plot_layout(nrow = 1) & \n  plot_annotation(tag_levels = "A") & \n  theme(plot.tag.position  = c(.935, .96))\n
Run Code Online (Sandbox Code Playgroud)\n

该代码生成一个两面板图。第一个面板的标签“A”位于正确的位置。但第二个面板的标签“B”不是:\n标签位置错误的绘图

\n

有多种方法可以解决该问题。例如,我可以plot.tag.position为每个面板单独指定:

\n
pLeft + theme(plot.tag.position  = c(.935, .96)) +\n  pRight + theme(plot.tag.position  = c(.785, .96)) + \n  plot_layout(nrow = 1) & \n  plot_annotation(tag_levels = "A")\n
Run Code Online (Sandbox Code Playgroud)\n

或者我可以plot_annotation()完全跳过并仅用于annotation_custom()每个面板。但这些都是糟糕的解决方案。问题是他们需要为每个面板单独指定标签坐标。有时我会在组装好的图中\xe2\x80\x94中有很多面板,比如说,在两列图中有N个\xc3\x97 2个面板。在这种情况下,我只想指定坐标两次:一次用于左侧列,一次用于右侧列。这可能吗?

\n

我查看了 patchwork 网站和 Stack Overflow 上的相关帖子,但没有找到任何解决方案。

\n

use*_*473 5

至少有四种基于拼凑的方法可以解决该问题:三种方法只为每列指定一次标记坐标,即使图形具有大量面板。(Thomas Lin Pedersen\xe2\x80\x99 出色的拼凑小插图帮助我找到了这些解决方案。)下面,我将说明这四种方法。他们都创造了这个数字:\n四面板图,标签位于正确位置。

\n
library(ggplot2)\nlibrary(patchwork)\n\npLeft <- ggplot(mtcars) + \n  geom_point(aes(mpg, disp)) + \n  scale_y_continuous("Left-hand panel", position = "left")\n\npRight <- pLeft + \n  scale_y_continuous("Right-hand panel", position = "right")\n
Run Code Online (Sandbox Code Playgroud)\n
\n
方法一
\n

当使用 patchwork 时,x / y意味着“将 ggplot 对象堆叠x在 ggplot 对象之上y”。

\n
((pLeft / pLeft) &  \n  theme(plot.tag.position  = c(.935, .96))) -\n  \n((pRight / pRight) & \n  theme(plot.tag.position  = c(.785, .96))) +\n  \nplot_annotation(tag_levels = "A") \n
Run Code Online (Sandbox Code Playgroud)\n
\n
方法 2:
\n
leftCol  <- (pLeft / pLeft)   & theme(plot.tag.position  = c(.935, .96))\nrightCol <- (pRight / pRight) & theme(plot.tag.position  = c(.785, .96))\n\nwrap_plots(leftCol, rightCol) &  # or "leftCol - rightCol"   \n  plot_annotation(tag_levels = "A") \n
Run Code Online (Sandbox Code Playgroud)\n
\n
方法3
\n
myPlot <- pLeft + pRight + pLeft + pRight + \n  plot_layout(nrow = 2) & \n  theme(plot.tag.position  = c(.935, .96)) &\n  plot_annotation(tag_levels = "A")\n\nfor (i in c(2, 4)) myPlot[[i]] <- myPlot[[i]] + theme(plot.tag.position  = c(.785, .96))\nmyPlot\n
Run Code Online (Sandbox Code Playgroud)\n
\n
方法 4
\n

这种方法依赖于 Paul Murrell 相对较新的ggrid包。相对于其他方法,它的优点是它允许您仅指定一对标签坐标,无论图形中有多少列或行。

\n
library(gggrid)  # devtools::install_github("pmur002/gggrid")\n\nmyPlot <- pLeft + pRight + pLeft + pRight + \n  plot_layout(nrow = 2) \n\nfor (i in 1:(length(myPlot$patches$plots) + 1)) {\n  myTag <- textGrob(LETTERS[i], x = .925, y = .95)\n  myPlot[[i]] <- myPlot[[i]] + grid_panel(myTag)\n}\nmyPlot\n
Run Code Online (Sandbox Code Playgroud)\n