0

Currently, I am trying to plot a dataset where there the number of facets is odd, leaving an incomplete final row in the plot. Ideally, I would like x-axis labels below each of the incomplete final row and the row above, where the bottom row is empty.

I have reviewed this question and answer, which appears to do exactly what I want. However, it appears that since this answer was last updated, something has changed in ggplot or gridExtra that breaks the solution when trying to save using ggsave. Instead of creating a valid file, the code prints the structure of the TableGrob to the console (included further down) and producing a corrupt 4KB PDF file (cannot be opened on OS X by QuickLook, Preview or Adobe Reader).

The code I have attempted to use is as follows, which I believe matches that in the original linked answer:

library(ggplot2)
library(grid)

facetAdjust <- function(x, pos = c("up", "down"))
{
  pos <- match.arg(pos)
  p <- ggplot_build(x)
  gtable <- ggplot_gtable(p); dev.off()
  dims <- apply(p$panel$layout[2:3], 2, max)
  nrow <- dims[1]
  ncol <- dims[2]
  panels <- sum(grepl("panel", names(gtable$grobs)))
  space <- ncol * nrow
  n <- space - panels
  if(panels != space){
    idx <- (space - ncol - n + 1):(space - ncol)
    gtable$grobs[paste0("axis_b",idx)] <- list(gtable$grobs[[paste0("axis_b",panels)]])
    if(pos == "down"){
      rows <- grep(paste0("axis_b\\-[", idx[1], "-", idx[n], "]"), 
        gtable$layout$name)
      lastAxis <- grep(paste0("axis_b\\-", panels), gtable$layout$name)
      gtable$layout[rows, c("t","b")] <- gtable$layout[lastAxis, c("t")]
    }
  }
  class(gtable) <- c("facetAdjust", "gtable", "ggplot"); gtable
}

d <- ggplot(diamonds, aes(carat, price, fill = ..density..)) +
xlim(0, 2) + stat_binhex(na.rm = TRUE) + theme(aspect.ratio = 1) + 
facet_wrap(~ color)

d <- facetAdjust(d)
ggsave("test.pdf",d)

When run, this produces the following console output:

Saving 7 x 7 in image
TableGrob (16 x 13) "layout": 33 grobs
    z         cells       name                                    grob
1   0 ( 1-16, 1-13) background          rect[plot.background.rect.239]
2   1 ( 4- 4, 4- 4)    panel-1                 gTree[panel-1.gTree.53]
...(shortened)...
32 31 ( 4-12,12-12)  guide-box                       gtable[guide-box]
33 32 ( 2- 2, 4-10)      title               text[plot.title.text.237]

...and also produces a 4KB PDF file that cannot be opened by QuickLook, Preview or Adobe Reader.

I have reviewed the facetAdjust function as best I can, but am not experienced enough to determine what the problem is. Does anyone have any suggestions on how to fix this problem?

Community
  • 1
  • 1
obfuscation
  • 1,023
  • 3
  • 16
  • 23
  • the print method is getting confused, try changing the order `class(gtable) <- c("facetAdjust", "ggplot", "gtable")` – baptiste Dec 15 '14 at 14:09
  • 1
    actually, looking at the original answer, you seem to have forgotten `print.facetAdjust`, so the next method is chosen as print.gtable which doesn't draw anything. – baptiste Dec 15 '14 at 14:11
  • Apologies for such a silly mistake - earlier I had removed it, because in my debugging it appeared it wasn't being called (probably due to another mistake I had made, but later fixed). Having added `print.facetAdjust` as listed it is now working properly, thanks. – obfuscation Dec 15 '14 at 14:51

1 Answers1

0

Rather silly, but had removed the print function whilst debugging another problem, and hadn't restored it properly. Adding the following function, as baptiste suggests, fixes the problem:

print.facetAdjust <- function(x, newpage = is.null(vp), vp = NULL) {
  if(newpage)
    grid.newpage()
  if(is.null(vp)){
    grid.draw(x)
  } else {
    if (is.character(vp)) 
      seekViewport(vp)
    else pushViewport(vp)
    grid.draw(x)
    upViewport()
  }
  invisible(x)
}
Community
  • 1
  • 1
obfuscation
  • 1,023
  • 3
  • 16
  • 23