1

Some months ago, I needed to remove one of the strips generated by a ggplot2 faceted plot. I found that someone had already asked in this question, and the answer worked pretty well:

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")

Today, I was trying to regenerate some figures that used this code and it didn't work to my surprise. Apparently, making a grob with ggplotGrob, modifying its contents and transforming it back to a ggplot2 object does not work anymore.

I am a bit clueless on how to proceed here. Any ideas on why this code does not work anymore?

I suspect that the package gridExtra may be the culprit. In my work machine where this code works, this package is in version 0.9.1, but in my laptop, where it doesn't work, I have 2.0.0. Since the gap between versions is quite large, I have no idea what change may be related to this problem.

Community
  • 1
  • 1
YuppieNetworking
  • 8,672
  • 7
  • 44
  • 65

1 Answers1

3

Update Setting strip.text.x or strip.text.y to element_blank() completely removes the strip.

library(ggplot2)

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

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

Original A point to note: ggplot grobs can't be transformed back into ggplot2 objects. But ggplot grobs can be made to behave a bit like a ggplot2 object.

Another point: In the link you provide, look down the list of solutions to Baptiste's solution. It is less dependent on the structure of the 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)

To make the grob behave more like a ggplot object:

#  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)

OR Wrap it up in a function:

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")
Sandy Muspratt
  • 31,719
  • 12
  • 116
  • 122
  • Excellent answer. So, in future versions of ggplot (>1.0.1) there is no ggplot class? – YuppieNetworking Oct 15 '15 at 09:25
  • Not quite. Currently, `ggsave` checks for a `ggplot` object. The ggplot grob (i.e., the object after `ggplotGrob (a)` ) is a gtable object but not a ggplot object, and hence ggsave fails. In the next version of ggplot, ggsave will save gtables. – Sandy Muspratt Oct 15 '15 at 10:38