迭代`TableGrob`中的条目以找到最大宽度?

时间:2013-06-20 13:44:12

标签: r r-grid gtable

请考虑这个经过修改但无耻的filched代码:

library(ggplot2)
library(gtable)
library(gridExtra)
p1 <- ggplot(
  data.frame(
    x=c("a","b","longer"),
    y=c("happy","sad","ambivalent about")),
  aes(x=factor(0),fill=x)) + 
  geom_bar() +
  geom_point(aes(y=seq(3),color=y))
p2 <- ggplot(
  data.frame(
    x=c("a","b","c"),
    y=c("happy","sad","ambivalent about life")),
    aes(x=factor(0),fill=y)) + 
geom_bar()

# Get the widths
gA <- ggplot_gtable(ggplot_build(p1))
gB <- ggplot_gtable(ggplot_build(p2))

# The parts that differs in width
leg1 <- with(gA$grobs[[8]], grobs[[1]]$widths[[4]])
leg2 <- with(gB$grobs[[8]], grobs[[1]]$widths[[4]])

# Set the widths
gA$widths <- gB$widths

# Add an empty column of "abs(diff(widths)) mm" width on the right of 
# legend box for gA (the smaller legend box)
gA$grobs[[8]] <- gtable_add_cols(gA$grobs[[8]], unit(abs(diff(c(leg1, leg2))), "mm"))

# Arrange the two charts
grid.newpage()
grid.arrange(gA, gB, nrow = 2)

在这些条件下,图例的放置不能正常工作,因为gA$grobs[[8]]有2个条目,代码明确访问第一个以确定所需的图例调整。

我想要做的是迭代gA$grobs[[8]]中的所有条目并找到要使用的最大宽度。

顺便说一句:

library(gtable)
a <- gtable(unit(1:3, c("cm")), unit(5, "cm"))
a # See, "TableGrob" exists (somewhat) ;)

我希望这能清除我打算做的事情。

感谢任何指针,Joh

1 个答案:

答案 0 :(得分:0)

恕我直言,你没有从该线程中选择最简单的答案。考虑这个更简单的方法,

rbind_gtable_max <- function (x, y) 
{
  stopifnot(ncol(x) == ncol(y))
  if (nrow(x) == 0) 
    return(y)
  if (nrow(y) == 0) 
    return(x)
  y$layout$t <- y$layout$t + nrow(x)
  y$layout$b <- y$layout$b + nrow(x)
  x$layout <- rbind(x$layout, y$layout)
  x$heights <- gtable:::insert.unit(x$heights, y$heights)
  x$rownames <- c(x$rownames, y$rownames)
  x$widths <- grid::unit.pmax(x$widths, y$widths)
  x$grobs <- append(x$grobs, y$grobs)
  x
}


gA <- ggplotGrob(p1)
gB <- ggplotGrob(p2)

both <- rbind_gtable_max(gA, gB)
grid.draw(both)

编辑如果想让图例框左对齐,那就更棘手了。这是因为ggplot2使用gtable将各种组件组合在一起,而gtable在一个单元格内没有理由。这对于诸如绘图面板之类的组件来说很好,它总是延伸到完整单元格(视口),但是引导凹槽具有固定的大小,因此显示为居中。

确实,您可能需要采用手动计算。为此,请注意在示例代码中,在覆盖gA$widths之前,您可以使用sum(gA$grobs[[8]]$width访问完整的图例宽度。