3

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

library(ggplot2)
library(patchwork)

pLeft <- ggplot(mtcars) + 
  geom_point(aes(mpg, disp)) + 
  scale_y_continuous("Left-hand panel", position = "left")

pRight <- pLeft + 
  scale_y_continuous("Right-hand panel", position = "right")

pLeft + pRight + 
  plot_layout(nrow = 1) & 
  plot_annotation(tag_levels = "A") & 
  theme(plot.tag.position  = c(.935, .96))

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

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

pLeft + theme(plot.tag.position  = c(.935, .96)) +
  pRight + theme(plot.tag.position  = c(.785, .96)) + 
  plot_layout(nrow = 1) & 
  plot_annotation(tag_levels = "A")

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

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

4

2 回答 2

1

一种解决方法可能是创建 2 个主题并将左侧主题添加到左侧的情节中,并将右侧主题添加到右侧的情节中。

library(ggplot2)
library(patchwork)

theme_left <- function(...) {
  theme_gray(...) %+replace% 
    theme(
      plot.tag.position = c(.935, .96)
    )
}

theme_right <- function(...) {
  theme_gray(...) %+replace% 
    theme(
      plot.tag.position = c(.785, .96)
    )
}

pLeft <- ggplot(mtcars) + 
  geom_point(aes(mpg, disp)) + 
  scale_y_continuous("Left-hand panel", position = "left") +
  theme_left()


pRight <- pLeft + 
  scale_y_continuous("Right-hand panel", position = "right") + 
  theme_right()

pLeft + pRight + 
  plot_layout(nrow = 1) & 
  plot_annotation(tag_levels = "A") 

在此处输入图像描述

于 2021-09-05T17:29:27.960 回答
1

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

library(ggplot2)
library(patchwork)

pLeft <- ggplot(mtcars) + 
  geom_point(aes(mpg, disp)) + 
  scale_y_continuous("Left-hand panel", position = "left")

pRight <- pLeft + 
  scale_y_continuous("Right-hand panel", position = "right")

方法 1

使用拼凑时,x / y表示“将 ggplot 对象堆叠在 ggplot 对象x之上y”。

((pLeft / pLeft) &  
  theme(plot.tag.position  = c(.935, .96))) -
  
((pRight / pRight) & 
  theme(plot.tag.position  = c(.785, .96))) +
  
plot_annotation(tag_levels = "A") 

方法 2:
leftCol  <- (pLeft / pLeft)   & theme(plot.tag.position  = c(.935, .96))
rightCol <- (pRight / pRight) & theme(plot.tag.position  = c(.785, .96))

wrap_plots(leftCol, rightCol) &  # or "leftCol - rightCol"   
  plot_annotation(tag_levels = "A") 

方法 3
myPlot <- pLeft + pRight + pLeft + pRight + 
  plot_layout(nrow = 2) & 
  theme(plot.tag.position  = c(.935, .96)) &
  plot_annotation(tag_levels = "A")

for (i in c(2, 4)) myPlot[[i]] <- myPlot[[i]] + theme(plot.tag.position  = c(.785, .96))
myPlot

方法 4

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

library(gggrid)  # devtools::install_github("pmur002/gggrid")

myPlot <- pLeft + pRight + pLeft + pRight + 
  plot_layout(nrow = 2) 

for (i in 1:(length(myPlot$patches$plots) + 1)) {
  myTag <- textGrob(LETTERS[i], x = .925, y = .95)
  myPlot[[i]] <- myPlot[[i]] + grid_panel(myTag)
}
myPlot
于 2021-09-07T14:22:26.693 回答