Viewports can be positioned with some precision. In the example below, the two legends are extracted then placed within their own viewports. The viewports are contained within coloured rectangles to show their positioning. Also, I placed the map and the scatterplot within viewports. Getting the text size and dot size right so that the upper left legend squeezed into the available space was a bit of a fiddle.
library(ggplot2); library(maps); library(grid); library(gridExtra); library(gtable)
ny <- subset(map_data("county"), region %in% c("new york"))
ny$region <- ny$subregion
p3 <- ggplot(dat2, aes(x = lng, y = lat)) +
geom_polygon(data=ny, aes(x = long, y = lat, group = group))
# Get the colour legend
(e1 <- p3 + geom_point(aes(colour = INST..SUB.TYPE.DESCRIPTION,
size = Enrollment), alpha = .3) +
geom_point() + theme_gray(9) +
guides(size = FALSE, colour = guide_legend(title = NULL,
override.aes = list(alpha = 1, size = 3))) +
theme(legend.key.size = unit(.35, "cm"),
legend.key = element_blank(),
legend.background = element_blank()))
leg1 <- gtable_filter(ggplot_gtable(ggplot_build(e1)), "guide-box")
# Get the size legend
(e2 <- p3 + geom_point(aes(colour=INST..SUB.TYPE.DESCRIPTION,
size = Enrollment), alpha = .3) +
geom_point() + theme_gray(9) +
guides(colour = FALSE) +
theme(legend.key = element_blank(),
legend.background = element_blank()))
leg2 <- gtable_filter(ggplot_gtable(ggplot_build(e2)), "guide-box")
# Get first base plot - the map
(e3 <- p3 + geom_point(aes(colour = INST..SUB.TYPE.DESCRIPTION,
size = Enrollment), alpha = .3) +
geom_point() +
guides(colour = FALSE, size = FALSE))
# For getting the size of the y-axis margin
gt <- ggplot_gtable(ggplot_build(e3))
# Get second base plot - the scatterplot
plot2 <- ggplot(mtcars, aes(mpg, hp)) + geom_point()
# png("p.png", 600, 700, units = "px")
grid.newpage()
# Two viewport: map and scatterplot
pushViewport(viewport(layout = grid.layout(2, 1)))
# Map first
pushViewport(viewport(layout.pos.row = 1))
grid.draw(ggplotGrob(e3))
# position size legend
pushViewport(viewport(x = unit(1, "npc") - unit(1, "lines"),
y = unit(.5, "npc"),
w = leg2$widths, h = .4,
just = c("right", "centre")))
grid.draw(leg2)
grid.rect(gp=gpar(col = "red", fill = "NA"))
popViewport()
# position colour legend
pushViewport(viewport(x = sum(gt$widths[1:3]),
y = unit(1, "npc") - unit(1, "lines"),
w = leg1$widths, h = .33,
just = c("left", "top")))
grid.draw(leg1)
grid.rect(gp=gpar(col = "red", fill = "NA"))
popViewport(2)
# Scatterplot second
pushViewport(viewport(layout.pos.row = 2))
grid.draw(ggplotGrob(plot2))
popViewport()
# dev.off()