use*_*473 3 r ggplot2 patchwork
我使用 patchwork 来组装用 ggplot2 制作的图。我还使用 patchwork 的plot_annotation()命令自动注释组装好的图\xe2\x80\x94,例如自动将“A”、“B”等放置在每个图的右上角。在大多数情况下,这很容易做到。但是,当绘图的轴标签位于不同位置时,很难在正确的位置获得注释。这是问题的最小说明:
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))\nRun Code Online (Sandbox Code Playgroud)\n该代码生成一个两面板图。第一个面板的标签“A”位于正确的位置。但第二个面板的标签“B”不是:\n
有多种方法可以解决该问题。例如,我可以plot.tag.position为每个面板单独指定:
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")\nRun Code Online (Sandbox Code Playgroud)\n或者我可以plot_annotation()完全跳过并仅用于annotation_custom()每个面板。但这些都是糟糕的解决方案。问题是他们需要为每个面板单独指定标签坐标。有时我会在组装好的图中\xe2\x80\x94中有很多面板,比如说,在两列图中有N个\xc3\x97 2个面板。在这种情况下,我只想指定坐标两次:一次用于左侧列,一次用于右侧列。这可能吗?
我查看了 patchwork 网站和 Stack Overflow 上的相关帖子,但没有找到任何解决方案。
\n至少有四种基于拼凑的方法可以解决该问题:三种方法只为每列指定一次标记坐标,即使图形具有大量面板。(Thomas Lin Pedersen\xe2\x80\x99 出色的拼凑小插图帮助我找到了这些解决方案。)下面,我将说明这四种方法。他们都创造了这个数字:\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")\nRun Code Online (Sandbox Code Playgroud)\n 当使用 patchwork 时,x / y意味着“将 ggplot 对象堆叠x在 ggplot 对象之上y”。
((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") \nRun Code Online (Sandbox Code Playgroud)\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") \nRun Code Online (Sandbox Code Playgroud)\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\nRun Code Online (Sandbox Code Playgroud)\n 这种方法依赖于 Paul Murrell 相对较新的ggrid包。相对于其他方法,它的优点是它允许您仅指定一对标签坐标,无论图形中有多少列或行。
\nlibrary(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\nRun Code Online (Sandbox Code Playgroud)\n