0
votes

I'm working with a plot analogous to the following:

ggplot(data=mtcars, aes(x=wt, y=mpg, color=carb)) +
geom_line() + facet_grid(gear ~ .) + 
ggtitle(expression("Title")) +
labs(caption = "Sources: Compustat, Author's Calculations") + 
theme(plot.title = element_text(size = 20, hjust = 0.5), 
plot.caption=element_text(size=8, hjust=.5),
strip.background = element_blank(), 
strip.text = element_blank(), 
legend.title = element_blank())

I'm trying to do the following:

  • Insert a legend beneath each of the 3 facets, each legend specific to the facet above it.
  • Insert one plot title (as opposed to the same title above each facet).
  • Insert one caption beneath the final facet (as opposed to three captions beneath each facet).

I was able to reproduce this example on assigning a legend to each facet. However, the plot title was placed above and the caption below each facet. Also, this example uses facet_wrap and not facet_grid.

Thank you in advance.

1

1 Answers

1
votes
library(dplyr)
library(ggplot2)

tempgg <- mtcars %>% 
  group_by(gear) %>% 
  do(gg = {ggplot(data=., aes(x=wt, y=mpg, color=carb)) +
      geom_point() + 
      labs(x = NULL) +
      guides(color = guide_colorbar(title.position = "left")) +
      theme(plot.title = element_text(size = 20, hjust = 0.5), 
            plot.caption=element_text(size=8, hjust=.5),
            legend.position = "bottom")}) 

tempgg$gg[1][[1]] <- tempgg$gg[1][[1]] + labs(title = "Top title")
tempgg$gg[3][[1]] <- tempgg$gg[3][[1]] + labs(x = "Axis label", caption = "Bottom caption")

tempgg %>% gridExtra::grid.arrange(grobs = .$gg)

enter image description here

This isn't the most elegant way to do it. Each of the three grobs gets an equal space when you grid.arrange them, so the first and last ones are squished from the title and caption taking up space. You could add something like heights = c(3,2,3) inside the grid.arrange call, but you'd have to fiddle with each of the heights to get it to look right, and even then it would be a visual approximation, not exact.

To do it the more precise way, you'd need to look at the underlying gtables in each of the grobs. https://stackoverflow.com/users/471093/baptiste is the expert on that.


Update:

I used a @baptiste solution, which is still not particularly elegant, but gives you the same plot space for each panel. Use this snippet in place of the last line above.

tempggt <- tempgg %>% do(ggt = ggplot_gtable(ggplot_build(.$gg))) %>% .$ggt
gg1 <- tempggt[[1]]
gg2 <- tempggt[[2]]
gg3 <- tempggt[[3]]

gridExtra::grid.arrange(gridExtra::rbind.gtable(gg1, gg2, gg3))