【问题标题】:Ignore x-label alignment with multiple plots in patchwork: is this possible?忽略 x-label 对齐与拼凑而成的多个图:这可能吗?
【发布时间】:2020-06-10 13:25:33
【问题描述】:

我真的很喜欢 patchwork 包,多个地块的对齐通常比其他包(cowplot/gridextra)更好也更容易实现。

但是,有一件事我无法解决:是否可以在拼凑中忽略 x 轴对齐,而只对齐所有其他元素?或者手动调整拼凑中的这个x轴对齐后缀? 见附图:如果可能,我希望补丁 B 和 C (Petal.Length) 中的 x 轴标题更靠近 x 轴。

生成图像的代码:

library(ggplot2)
library(patchwork)

plot.1 <- ggplot(iris, aes(x = Species, y = Petal.Width)) +
  geom_boxplot() +
  scale_x_discrete(labels = c("A very\nvery\nlong\nlabel", "","")) +
  labs(x = element_blank())

plot.2 <- ggplot(iris, aes(x = Petal.Length, y = Petal.Width)) +
  geom_point()

(plot.1 |plot.2)/(plot.2|plot.1) + 
  plot_annotation(tag_levels = "A")

【问题讨论】:

  • 包作者在this GitHub issue 中的一个cmets 表明这可能是不可能的。但希望有人会提出解决方法!
  • 感谢您指出这一点,我还没有注意到这个问题!我希望有人能找到解决方法。这可能可以用 cowplot plot_grid 函数解决,但我的实际情节更复杂,不幸的是,我在 cowplot 包中遇到了其他问题:github.com/wilkelab/cowplot/issues/31#issuecomment-389193848

标签: r ggplot2 alignment patchwork


【解决方案1】:

OP 示例

library(ggplot2)
library(patchwork)

plot.1 <- ggplot(iris, aes(x = Species, y = Petal.Width)) +
  geom_boxplot() +
  scale_x_discrete(labels = c("A very\nvery\nlong\nlabel", "","")) +
  labs(x = element_blank())

plot.2 <- ggplot(iris, aes(x = Petal.Length, y = Petal.Width)) +
  geom_point()

(plot.1 | plot.2) / 
  (plot.2 | plot.1) + 
  plot_annotation(tag_levels = "A")

使用负边距

我花了一段时间才意识到问题源于 需要对齐axis.texts 和axis.titles 的混合。 尽管它们在语法上是不同的元素, 分类轴文本服务于大部分或全部 连续轴标题的实际功能。 标题将始终在对齐的文本区域之外与网格对齐。 单独的理由不能解决这个问题,但负边距可以。

注意事项:

  • 您需要的负边距值取决于图中的其他比例因子,因此这是 在最后抛光 解决方案之一。 -50 在这种情况下有效,但我需要使用其他值
  • 它也适用于 y 轴
  • 我弄乱了括号,但除了额外的theme() 层之外,绘图规范是相同的
  • 您通常不希望在单个绘图定义中包含此负边距主题 sn-p,因为它似乎会导致那里出现错误,并且您将无法迭代地细化这样的保证金值,至少如果您的脚本/Rmd 很长和/或复杂,则不容易。这确实是仅在使用patchwork 组装图的级别上的问题,因此最好在定义拼凑组装的地方进行这样的抛光调整,正如我在这里展示的那样。
(plot.1 | (
  plot.2 +
    theme(axis.title.x = element_text(margin = margin(t = -50, unit = "pt"))))
) / (
  (plot.2 +
     theme(axis.title.x = element_text(margin = margin(t = -50, unit = "pt")))) | 
    plot.1
) + 
  plot_annotation(tag_levels = "A")

【讨论】:

    【解决方案2】:

    我发现了一个黑客。如果使用函数 patchwork::patchworkGrob,绘图将存储在可编辑的 gtable 中。您只需要在表格中找到正确的布局值。每个布局部分都有可以编辑的“t r l b”尺寸(我相信顶部、右侧、左侧、底部)。就我而言,我想更改“xlab-b”的底部值。更改值后,可以使用 grid::grid.draw() 绘制 gtable。如果需要,可以以类似的方式以类似的方式更改 y 轴位置 (ylab-l)。

    library(grid) # should be loaded already, just to be sure.
    
    # Unadjusted patchwork:
    plots <- (plot.1 |plot.2)/(plot.2|plot.1) + 
      plot_annotation(tag_levels = "A")
    
    # create gTable object
    plots.gtable <- patchworkGrob(plots)
    
    # edit gtable object:
    # tables are found in the list ‘plots.gtable$grobs’
    # Second and fourth grobs in the list are the TableGrobs to edit:
    # First edit panel B:
    plots.gtable$grobs[[2]]$layout[
      plots.gtable$grobs[[2]]$layout$name == "xlab-b",
      ]$b[2] <- 12 # change this number, for me 12 worked fine
    # Ends with $b[2] because we only want to adjust position of 
    # the x-axis title of panel B.
    # To adjust the position of the x-axis title of both plot A and B, 
    # just leave out the [2].
    
    # Now access lower two patchwork TableGrobs:
    # edit panel C:
    plots.gtable$grobs[[4]]$layout[
      plots.gtable$grobs[[4]]$layout$name == "xlab-b",
      ]$b[1] <- 12
    
    # plot the adjusted figure:
    grid::grid.newpage()
    grid::grid.draw(plots.gtable)
    
    

    edited-patchwork-result

    编辑 29-01-2021:我认为 Paul McMurdie 的最新回答比我在这里提到的要容易。

    【讨论】:

      猜你喜欢
      • 2020-04-09
      • 2021-11-07
      • 2021-10-17
      • 2021-05-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-10
      相关资源
      最近更新 更多