【问题标题】:using patchwork to annotate plots that have labels in different positions使用拼凑来注释在不同位置有标签的图
【发布时间】:2021-11-02 23:32:03
【问题描述】:

我使用拼凑拼凑用 ggplot2 制作的图。我还使用 patchwork 的 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 上的相关帖子,但没有找到任何解决方案。

【问题讨论】:

    标签: r ggplot2 patchwork


    【解决方案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") 
    

    【讨论】:

    • 谢谢。我喜欢这段代码,我发现它有效。但我正在寻找一种解决方案,但允许我为每个面板(或行)指定标签坐标一次,而不是为每个单独的面板指定一次——即使图中有很多面板。也就是说,我不想在单个面板中添加任何东西——甚至像theme_left()theme_right() 这样简单的东西也不行。 (除其他外,将坐标添加到各个面板会使重新排列面板变得更加麻烦 - 例如,将面板从左侧列移动到右侧列。)
    【解决方案2】:

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

    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 对象 x 堆叠在 ggplot 对象 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
    

    【讨论】:

      猜你喜欢
      • 2020-11-27
      • 2021-08-19
      • 2021-11-17
      • 2021-12-07
      • 2020-10-10
      • 1970-01-01
      • 2021-02-11
      • 2021-10-17
      • 1970-01-01
      相关资源
      最近更新 更多