2

I just wanted to plot multiple facets using ggplot2 in combination with for loop and found the solution in this postggplot2-plots-over-multiple-pages.

However, I want to modify appearances of these facets with ggplotGrop for reducing the strip size of facets after this for loop.

I am providing here reproducible example of previous question for only plotting facets

library(ggplot2)
library(vcd) # For the Baseball data
data(Baseball)

pdf("baseball.pdf", 7, 5)

aa<- for (i in seq(1, length(unique(Baseball$team87)), 6)) {
       print(ggplot(Baseball[Baseball$team87 %in% levels(Baseball$team87)[i:(i+5)], ], 
                      aes(hits86, sal87)) + 
        geom_point() +
        facet_wrap(~ team87) +
        scale_y_continuous(limits=c(0, max(Baseball$sal87, na.rm=TRUE))) +
        scale_x_continuous(limits=c(0, max(Baseball$hits86))) +
        theme_bw())
    }
    dev.off()

want to implement ggplotGrob to reduce the strip size.

library(gridExtra)
         library(grid)
         g = ggplotGrob(aa)

         pos =  c(unique(subset(g$layout, grepl("panel", g$layout$name), select = t)))
         for(i in pos) g$heights[i-1] = unit(0.4,"cm")

         grobs = which(grepl("strip", g$layout$name))
         for(i in grobs) g$grobs[[i]]$heights <-  unit(1, "npc") 

        grid.draw(g)
        dev.off()      

Error in plot_clone(plot) : attempt to apply non-function

I just wonder how to implement ggplotGrop to that for loop.

Community
  • 1
  • 1
Alexander
  • 4,527
  • 5
  • 51
  • 98

1 Answers1

2

The main probleme is that you're using ggplotGrob on an the wrong object. You have to use it inside each loop. Then you must grid.arrange to make the multipage pdf

First method: with a trick as ggplotGrob create a blank page

pdf("baseball.pdf", 7, 5)

for (i in seq(1, length(unique(Baseball$team87)), 6)) {
  temp <- ggplot(Baseball[Baseball$team87 %in% levels(Baseball$team87)[i:(i+5)], ], 
               aes(hits86, sal87)) + 
          geom_point(na.rm=TRUE) + ## to avoid warnings
          facet_wrap(~ team87) +
          scale_y_continuous(limits=c(0, max(Baseball$sal87, na.rm=TRUE))) +
          scale_x_continuous(limits=c(0, max(Baseball$hits86))) +
          theme_bw()
  pdf(file=NULL) ## because ggplotGrob will create a blank page
  g <- ggplotGrob(temp)
  pos =  c(unique(subset(g$layout, grepl("panel", g$layout$name), select = t)))
  for(i in pos) g$heights[i-1] = unit(0.4,"cm")

  grobs = which(grepl("strip", g$layout$name))
  for(i in grobs) g$grobs[[i]]$heights <-  unit(1, "npc") 
  dev.off() ## to close the fake device
  grid.arrange(g)



}

dev.off()

Second method: to avoid using fake device

plotlist <- list()
j <- 1

for (i in seq(1, length(unique(Baseball$team87)), 6)) {
  temp <- ggplot(Baseball[Baseball$team87 %in% levels(Baseball$team87)[i:(i+5)], ], 
               aes(hits86, sal87)) + 
          geom_point(na.rm=TRUE) +
          facet_wrap(~ team87) +
          scale_y_continuous(limits=c(0, max(Baseball$sal87, na.rm=TRUE))) +
          scale_x_continuous(limits=c(0, max(Baseball$hits86))) +
          theme_bw()
  g <- ggplotGrob(temp)
  pos =  c(unique(subset(g$layout, grepl("panel", g$layout$name), select = t)))
  for(i in pos) g$heights[i-1] = unit(0.4,"cm")

  grobs = which(grepl("strip", g$layout$name))
  for(i in grobs) g$grobs[[i]]$heights <-  unit(1, "npc") 

  plotlist[[j]] <- g
  j <- j+1


}
pdf("baseball.pdf", 7, 5)

for (i in (1:length(plotlist))) {
  grid.arrange(plotlist[[i]])
}

dev.off()

Actually, you can even use grid.arrange and ggplotGrob, without using facet to make all more customisable.

timat
  • 1,480
  • 13
  • 17