在ggplot中将多个图形堆叠在一起

Stacking multiple figures together in ggplot

我正在尝试制作可发布的图形,其中一个图形的底轴(带有刻度线)与它下面的图形的顶轴干净地结合在一起。这是它的外观示例,尽管每个面板上都没有刻度线:

这是我的尝试,只需使用 grid.arrange:


#Libraries:

library(ggplot2)
library(dplyr)
library(gridExtra)

#Filter to create two separate data sets:

dna1 <- DNase %>% filter(Run == 1)
dna2 <- DNase %>% filter(Run == 2)

#Figure 1:

dna1_plot <- ggplot(dna1, aes(x = conc, y = density)) + geom_point() + theme_classic() + 
  theme(axis.title.x = element_blank())

#Figure 2: 

dna2_plot <- ggplot(dna2, aes(x = conc, y = density)) + geom_point() + theme_classic() 

#Using grid.arrange to combine:

dna <- grid.arrange(dna1_plot, dna2_plot, nrow = 2)

并尝试对情节边距进行一些调整,尽管这似乎不起作用:


dna1_plot_round2 <- ggplot(dna1, aes(x = conc, y = density)) + geom_point() + theme_classic() + 
  theme(axis.title.x = element_blank(), 
        plot.margin = (0,0,0,0), "cm")

dna2_plot_round2 <- ggplot(dna2, aes(x = conc, y = density)) + geom_point() + theme_classic() +
  theme(plot.margin = unit(c(-0.5,-1,0,0), "cm"))

dna_round2 <- grid.arrange(dna1_plot_round2, dna2_plot_round2, nrow = 2)

有谁知道在 ggplot 中堆叠这样的图形的最佳方法吗?有没有比使用 grid.arrange 更好的方法?如果可能的话,最好看看如何做到这一点 with/without 每个 x 轴上的刻度线也是如此。

谢谢!

你不需要任何非原生的 ggplot 东西。将您的数据保存在一个数据框中并使用 facet_grid.

dna <- DNase %>% filter(Run %in% 1:2)

ggplot(dna, aes(x = conc, y = density)) + 
  geom_point() + 
  theme_bw() + 
  facet_grid(rows = vars(Run)) +
  theme(panel.spacing = unit(0, "mm"))

R 包 deeptime 有一个名为 ggarrange2 的函数可以实现这一点。它不像 grid.arrange(和 ggarrange)那样只是将图粘贴在一起,而是将所有图的所有轴和轴标签排列起来。

# remove bottom axis elements, reduce bottom margin, add panel border
dna1_plot_round2 <- ggplot(dna1, aes(x = conc, y = density)) + geom_point() + theme_classic() + 
      theme(axis.text.x = element_blank(), axis.ticks.x = element_blank(), axis.title.x = element_blank(),
      plot.margin = margin(0,0,-.05,0, "cm"), panel.border = element_rect(fill = NA))
# reduce top margin (split the difference so the plots are the same height), add panel border
dna2_plot_round2 <- ggplot(dna2, aes(x = conc, y = density)) + geom_point() + theme_classic() +
      theme(plot.margin = margin(-.05,0,0,0, "cm"), panel.border = element_rect(fill = NA))
dna_round2 <- ggarrange2(dna1_plot_round2, dna2_plot_round2, nrow = 2)

你也可以试试最近的 patchwork 包,虽然我对它没有太多经验。

请注意,虽然 Gregor 的答案对于这个特定示例可能没问题,但这个答案可能更适合遇到此问题的其他人(请参阅问题顶部的示例)。

就您的目的而言,我相信 Gregor Thomas 的回答是最好的。但是,如果您处于 facets 不是组合两个图的最佳选择的情况下,新的包 {{patchwork}} 比我见过的任何替代方案都能更优雅地处理这个问题。

Patchwork 还提供了许多选项,用于在组合图周围添加注释。 readME and vignettes 将帮助您入门。

library(patchwork)
(dna1_plot / dna2_plot) +
  plot_annotation(title = "Main title for combined plots")

编辑以更好地解决@Cameron 的问题。

根据 package creator,{{patchwork}} 不会在地块之间添加任何 space。上面示例中的白色 space 是由于每个 ggplot 周围的边距。这些边距可以使用 theme() 中的 plot.margin 参数进行调整,它采用上、右、下和左边距的数字向量。

在下面的示例中,我将 dna1_plot 的底部边距设置为 0,并去除所有底部 x 轴刻度和文本。我还将 dna2_plot 的上边距设置为 0。这样做 nearly 使两个图中的 y 轴线接触。

dna1_plot <- ggplot(dna1, aes(x = conc, y = density)) + geom_point() + theme_classic() + 
  theme(axis.title.x = element_blank(),
        axis.ticks.x = element_blank(),
        axis.text.x = element_blank(),
        plot.margin = unit(c(1,1,0,1), "mm"))

#Figure 2: 

dna2_plot <- ggplot(dna2, aes(x = conc, y = density)) + geom_point() + theme_classic() +
  theme(plot.margin = unit(c(0,1,1,1), "mm"))

(dna1_plot / dna2_plot)