在一个轴上删除 strip.background:没有层

Removing strip.background on one axis: no layers

几个月前,我需要删除由 ggplot2 多面图生成的条带之一。我发现 this question 里已经有人问过了,而且回答得很好:

library(ggplot2)
a <- ggplot(mtcars, aes(mpg, hp)) +
  geom_point() +
  facet_grid(cyl~gear) 

strip.remover <- function(ggp, what="x") {
  require(gridExtra)

  zeroGrob <- function() {
    g0 <- grob(name="NULL")
    class(g0) <- c("zeroGrob",class(g0))
    g0
  }

  g <- ggplotGrob(ggp)

  g$grobs <- lapply(g$grob, function(gr) {
    if (any(grepl(paste0("strip.text.", what),names(gr$children)))) {
      gr$children[[grep("strip.background",names(gr$children))]] <- zeroGrob()
      gr$children[[grep("strip.text",names(gr$children))]] <- zeroGrob()
    }
    return(gr)
  }
  )

  class(g) = c("arrange", "ggplot",class(g)) 
  g
}

strip.remover(a, "y")

今天,我试图重新生成一些使用此代码的图形,但令我惊讶的是它并没有起作用。显然,使用 ggplotGrob 进行 grob,修改其内容并将其转换回 ggplot2 对象不再有效。

我对如何继续这里有点无能为力。关于为什么此代码不再有效的任何想法?

我怀疑包 gridExtra 可能是罪魁祸首。在我的工作机器上,这个代码可以工作,这个包的版本是 0.9.1,但是在我的笔记本电脑上,它不起作用,我有 2.0.0。由于版本之间的差距很大,我不知道这个问题可能与什么变化有关。

更新strip.text.xstrip.text.y 设置为 element_blank() 完全删除条带。

library(ggplot2)

a <- ggplot(mtcars, aes(mpg, hp)) +
  geom_point() +
  facet_grid(cyl~gear)

a + theme(strip.text.y = element_blank())

原创 需要注意的一点:ggplot grobs 无法转换回 ggplot2 对象。但是可以使 ggplot grobs 的行为有点像 ggplot2 对象。

还有一点:在你提供的link中,往下看巴蒂斯特解法的解法列表。它不太依赖于 ggplot grob 的结构。

library(ggplot2)

a <- ggplot(mtcars, aes(mpg, hp)) +
  geom_point() +
  facet_grid(cyl~gear) 

library(grid)

# To remove the strip but keep the space
g <- ggplotGrob(a)
keep <- !grepl("strip-r", g$layout$name)
g$grobs <- g$grobs[keep]
g$layout <- g$layout[keep, ]
grid.newpage()
grid.draw(g)

# To remove the strip and the space
g = g[, -which(!keep)]
grid.newpage()
grid.draw(g)

要使 grob 的行为更像 ggplot 对象:

#  A print method for the plot
print.ggplotgrob <- function(x) {
   grid.newpage()   
   grid.draw(x)
}
class(g) = c("ggplotgrob", class(g)) 

g
ggsave("plotGrob.png", g)

将其包装在一个函数中:

strip.remover = function(plot, strip) {
    g <- ggplotGrob(plot); dev.off()
    if(!(strip == "t" | strip == "r") )  stop("strip must be either 't' or 'r'")

    keep <- !grepl(paste0("strip-", strip), g$layout$name)
    g$grobs <- g$grobs[keep]
    g$layout <- g$layout[keep, ]

    class(g) <- c("ggplotgrob",  class(g)) 
    g
}

#  A print method for the plot
print.ggplotgrob <- function(x) {
    library(grid)
    grid.newpage()   
    grid.draw(x)
    }


# Try it out
gtplot <- strip.remover(a, "t")
gtplot
ggsave("grob.png", gtplot)

strip.remover(a, "r")
strip.remover(a, "wrong")