10

I am attempting to align the left and right edges of 4 ggplot choropleth maps using this method. I am unable to do this though.

Original plot:

library(ggplot2); library(gridExtra)
crimes <- data.frame(state = tolower(rownames(USArrests)), USArrests)
states_map <- map_data("state")
plot1 <- ggplot(crimes, aes(map_id = state)) +
    geom_map(aes(fill = Murder), map = states_map) +
    expand_limits(x = states_map$long, y = states_map$lat) + 
    scale_fill_gradient(low="white", high="darkgreen", name="Really Long Name 1")


plot2 <- plot1 + scale_fill_gradient(name="Really Long Name 2 and then some")
plot3 <- plot1 + scale_fill_gradient(name="Short 3") 
plot4 <- plot1 + scale_fill_gradient(name="Really Long Name 4")

grid.arrange(plot1, plot3, plot2, plot4, ncol = 2)

Attempt to align plot edges (same result):

p1 <- ggplotGrob(plot1)
p2 <- ggplotGrob(plot2)
p3 <- ggplotGrob(plot3)
p4 <- ggplotGrob(plot4)

maxWidth <- grid::unit.pmax(p1$widths[2:3], p2$widths[2:3], p3$widths[2:3], p4$widths[2:3])
p1$widths[2:3] <- as.list(maxWidth)
p2$widths[2:3] <- as.list(maxWidth)
p3$widths[2:3] <- as.list(maxWidth)
p4$widths[2:3] <- as.list(maxWidth)

grid.arrange(p1, p3, p2, p4, ncol = 2) 

enter image description here

PS: Assume I need to use grid arrange and the legends are not actually the same scale so facet_grid is out etc.

Uwe
  • 41,420
  • 11
  • 90
  • 134
Tyler Rinker
  • 108,132
  • 65
  • 322
  • 519
  • 1
    If it is only the legend title that is the issue, have you considered placing it horizontally in the top or bottom? I.e. `plot1 + theme(legend.position='bottom', legend.direction='horizontal')` – MrGumble Jul 04 '13 at 06:05
  • as suggested in the comments for the link you posted, you probably wanted to use `widths[2:5]` throughout to include the legend in the comparison of units. Note that it will result in the same legend centering as in @kohske's first answer, because the guide grob centers itself in the allocated viewport. – baptiste Jul 04 '13 at 13:38
  • I tried the `widths[2:5]` and it resulted in very odd placements. – Tyler Rinker Jul 04 '13 at 14:26
  • I lied this works. @Baptise can you provide this as an answer for future searchers? – Tyler Rinker Jul 04 '13 at 14:39
  • i've edited the original post, so I'd rather close your question as a duplicate :) – baptiste Jul 04 '13 at 14:58
  • This may be sensible but we'd lose Kohske's answer unless he transfers it there. – Tyler Rinker Jul 04 '13 at 15:20

2 Answers2

9

Here is an example:

library(gtable)
grid.draw(cbind(rbind(p1, p2, size="last"), rbind(p3, p4, size="last"), size = "first"))

enter image description here


Updated

This is a bad hack so I don't recommend to use. Probably this will not work in future.

gt <- cbind(rbind(p1, p2, size="last"), rbind(p3, p4, size="last"), size = "first")
for (i in which(gt$layout$name == "guide-box")) {
  gt$grobs[[i]] <- gt$grobs[[i]]$grobs[[1]]
}
grid.draw(gt)

enter image description here

Tyler Rinker
  • 108,132
  • 65
  • 322
  • 519
kohske
  • 65,572
  • 8
  • 165
  • 155
  • 2
    +1 Good solution. I wonder whether it's possible to align the legends too, such that only the space to the right of the plots increases. – Sven Hohenstein Jul 04 '13 at 06:41
  • oops, `gt` is `gt <- cbind(rbind(p1, p2, size="last"), rbind(p3, p4, size="last"), size = "first"))` – kohske Jul 04 '13 at 13:08
  • so, let me try to understand: `gt$grobs[[i]]` is a gtable, but it is somehow just wrapping another gtable with the actual grobs, the child gtable being centered within its container? – baptiste Jul 04 '13 at 13:49
  • @baptiste exactly, `gtable` of `gtable` generates a wrapper viewport at the drawing time. This is bad hack and now Paul implemented the new hook `grid::makeContext`. Perhaps it'd be better to rewrite some parts of `gtable`. You can find our effort here: http://rpubs.com/kohske/815 . – kohske Jul 04 '13 at 14:05
  • yes, I forgot a lot of this discussion since last year, unfortunately, and it seems to have remained the status quo since then. Paul Murrell has rewritten gtable using his new functions, by-the-way (see his fork on github), but I'm not sure what that would mean for the existing guides part. – baptiste Jul 04 '13 at 14:08
  • Note that this will be part of a future [blog post](https://dl.dropboxusercontent.com/u/61803503/Errors/chloropleth.html) I will be posting. If anyone has anything to add about the plot (particularly the final one) please email @ tyler.rinker@gmail.com – Tyler Rinker Jul 04 '13 at 15:24
2

Using cowplot package:

library(cowplot)
plot_grid(plot1, plot3, plot2, plot4, ncol = 2, align = "v")

enter image description here

zx8754
  • 52,746
  • 12
  • 114
  • 209