在ggplot 2中对齐多个plot时,有些有legend,而另一些没有,为什么?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (280)

当我的一些图形有一个legend,而另一些则没有的时候,我无法让它工作。

以下是一个例子:

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)

使用这段代码,我得到了以下结果:

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

然后我试了三次,有着不同的传说尺寸,但现在已经不起作用了:

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)

这导致了以下数字:

二次

我在这里找到的答案和其他有关这个主题的问题的主要问题是人们对向量“玩”了很多。myGrob$widths却没有解释他们为什么要这么做。我见过人们修改myGrob$widths[2:5]其他myGrob$widths[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)
}
提问于
用户回答回答于

使用gtable功能gtable_add_cols()若要将这些列添加到GBgtable中,请执行以下操作:

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

然后继续arrangeGrob().

egg:

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

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

热门问答

腾讯云广州一区DNS变更,需要怎么操作?

思潮澎湃轻描淡写的生活,但思潮澎湃
推荐
我也收到相关的通知了,这里分享下~ 2019年1月31日,腾讯云将对广州地区旧的基础网络DNS服务器(10.225.30.181、10.225.30.223)进行下线。在此期间,腾讯云提供最新的DNS服务器供您更新使用。 我们建议您尽快将DNS服务器配置进行更新,并且我们为您提供...... 展开详请

CMQ创建队列成功,紧接着发送消息,报队列不存在?

CreateQueue成功后,创建队列的时间为1s,您可以等待下在sendMessage

云呼叫中心只能用户自己开发吗?

腾讯云通信团队

腾讯 · 腾讯云通信团队 (已认证)

腾讯高级产品经理
推荐

目前呼叫中心只有API文档,需要用户自己开发。如果用户需要saas系统的呼叫中心可以使用智能外呼机器人:https://cloud.tencent.com/product/ccsr

ios端推流setRenderRotation无效?

西风

renzha.net · 站长 (已认证)

www.renzha.net
推荐

你有没有调整观众端表现,即通过对 LivePushConfig 中的homeOrientation设置项进行配置,它控制的是观众端看到的视频宽高比是16:9还是6:19,调整后的结果可以用播放器查看以确认是否符合预期。

腾讯云直播 CNAME 记录添加 的 值是多少???

西风

renzha.net · 站长 (已认证)

www.renzha.net
推荐
第一步:域名备案 控制台进行域名提交管理前,需对域名进行备案,详情请查看 域名备案 和 域名备案和配置常见问题 文档。 第二步:添加域名 在视频直播菜单栏内选择【域名管理】,在域名管理页面可以看到已创建域名、类型、状态、添加时间和操作。 可添加和管理的域名类型有播放域名和推流域...... 展开详请

【建议】【API】使用API创建子网的时候允许指定已有路由表?

推荐

控制台使用的是新的接口,批量创建子网,https://cloud.tencent.com/document/product/215/31960,可以指定路由表。terraform开发的时候是基于api2.0开发的,还没有这个接口,因此暂时无法使用

所属标签

扫码关注云+社区