在ggplot2中对齐多个绘图,当有些图形没有图例时 - 代码日志

在ggplot2中对齐多个绘图,当有些图形没有图例时

我使用了指示here的方法对齐共享相同横坐标的图。

但是当我的一些图形有一个传说,而另一些没有图形时,我不能使它工作。

这是一个例子:

library(ggplot2)
library(reshape2)
library(gridExtra)

x = seq(0, 10, length.out = 200)
y1 = sin(x)
y2 = cos(x)
y3 = sin(x) * cos(x)

df1 <- data.frame(x, y1, y2)
df1 <- melt(df1, id.vars = "x")

g1 <- ggplot(df1, aes(x, value, color = variable)) + geom_line()
print(g1)

df2 <- data.frame(x, y3)
g2 <- ggplot(df2, aes(x, y3)) + geom_line()
print(g2)

gA <- ggplotGrob(g1)
gB <- ggplotGrob(g2)
maxWidth <- grid::unit.pmax(gA$widths[2:3], gB$widths[2:3])
gA$widths[2:3] <- maxWidth
gB$widths[2:3] <- maxWidth
g <- arrangeGrob(gA, gB, ncol = 1)
grid::grid.newpage()
grid::grid.draw(g)

使用这段代码,我有以下结果:

enter image description here

我想要的是将x轴对齐,并且缺少的图例由空格填充。这可能吗?

编辑:

提出的最优雅的解决方案是Sandy Muspratt下面的解决方案。

我实现了它,它与两个图表相当好。

然后我尝试了三个,有不同的传奇大小,它不再工作了:

library(ggplot2)
library(reshape2)
library(gridExtra)

x = seq(0, 10, length.out = 200)
y1 = sin(x)
y2 = cos(x)
y3 = sin(x) * cos(x)
y4 = sin(2*x) * cos(2*x)

df1 <- data.frame(x, y1, y2)
df1 <- melt(df1, id.vars = "x")

g1 <- ggplot(df1, aes(x, value, color = variable)) + geom_line()
g1 <- g1 + theme_bw()
g1 <- g1 + theme(legend.key = element_blank())
g1 <- g1 + ggtitle("Graph 1", subtitle = "With legend")

df2 <- data.frame(x, y3)
g2 <- ggplot(df2, aes(x, y3)) + geom_line()
g2 <- g2 + theme_bw()
g2 <- g2 + theme(legend.key = element_blank())
g2 <- g2 + ggtitle("Graph 2", subtitle = "Without legend")

df3 <- data.frame(x, y3, y4)
df3 <- melt(df3, id.vars = "x")

g3 <- ggplot(df3, aes(x, value, color = variable)) + geom_line()
g3 <- g3 + theme_bw()
g3 <- g3 + theme(legend.key = element_blank())
g3 <- g3 + scale_color_discrete("This is indeed a very long title")
g3 <- g3 + ggtitle("Graph 3", subtitle = "With legend")

gA <- ggplotGrob(g1)
gB <- ggplotGrob(g2)
gC <- ggplotGrob(g3)

gB = gtable::gtable_add_cols(gB, sum(gC$widths[7:8]), 6)

maxWidth <- grid::unit.pmax(gA$widths[2:5], gB$widths[2:5], gC$widths[2:5])
gA$widths[2:5] <- maxWidth
gB$widths[2:5] <- maxWidth
gC$widths[2:5] <- maxWidth

g <- arrangeGrob(gA, gB, gC, ncol = 1)
grid::grid.newpage()
grid::grid.draw(g)

这得出如下图:
enter image description here

我在这里找到的答案和关于这个问题的其他问题的主要问题是,人们通过向量myGrob $宽度“玩”相当多,而没有真正解释为什么他们在做这件事情。我看到人们修改myGrob $ width [2:5]其他的myGrob $ width [2:3],我找不到任何文档来解释这些列。

我的目标是创建一个泛型函数,如:

AlignPlots <- function(...) {
  # Retrieve the list of plots to align
  plots.list <- list(...)

  # Initialize the lists
  grobs.list <- list()
  widths.list <- list()

  # Collect the widths for each grob of each plot
  max.nb.grobs <- 0
  longest.grob <- NULL
  for (i in 1:length(plots.list)){
    if (i != length(plots.list)) {
      plots.list[[i]] <- plots.list[[i]] + theme(axis.title.x = element_blank())
    }

    grobs.list[[i]] <- ggplotGrob(plots.list[[i]])
    current.grob.length <- length(grobs.list[[i]])
    if (current.grob.length > max.nb.grobs) {
      max.nb.grobs <- current.grob.length
      longest.grob <- grobs.list[[i]]
    }

    widths.list[[i]] <- grobs.list[[i]]$widths[2:5]
  }

  # Get the max width
  maxWidth <- do.call(grid::unit.pmax, widths.list)

  # Assign the max width to each grob
  for (i in 1:length(grobs.list)){
    if(length(grobs.list[[i]]) < max.nb.grobs) {
      grobs.list[[i]] <- gtable::gtable_add_cols(grobs.list[[i]],
                                                 sum(longest.grob$widths[7:8]),
                                                 6)
    }
    grobs.list[[i]]$widths[2:5] <- as.list(maxWidth)
  }

  # Generate the plot
  g <- do.call(arrangeGrob, c(grobs.list, ncol = 1))

  return(g)
}
现在可能有更简单的方法来执行此操作,但是您的代码并没有太大的错误。

确保gA中第2列和第3列的宽​​度与gB中的第2列和第3列的宽​​度相同时,请检查两个gtables的宽度:gA $ width和gB $ width。您将注意到,gA gtable在gB gtable中不存在两个附加列,即宽度为7和8.使用gtable函数gtable_add_cols()将列添加到gB gtable中:

gB = gtable::gtable_add_cols(gB, sum(gA$widths[7:8]), 6)

然后继续安排Grob()….

编辑:更一般的解决方案

包蛋(github可用)是实验性的和脆弱的,但是与您修改的一组图很好地合作。

# install.package(devtools)
devtools::install_github("baptiste/egg")

library(egg)
grid.newpage()
grid.draw(ggarrange(g1,g2,g3, ncol = 1))

enter image description here

http://stackoverflow.com/questions/41569817/align-multiple-plots-in-ggplot2-when-some-have-legends-and-others-dont

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:在ggplot2中对齐多个绘图,当有些图形没有图例时