Skip to content

Instantly share code, notes, and snippets.

@scbrown86
Created February 8, 2018 04:40
Show Gist options
  • Save scbrown86/3af317eb4ab692342e0ae46237dbace2 to your computer and use it in GitHub Desktop.
Save scbrown86/3af317eb4ab692342e0ae46237dbace2 to your computer and use it in GitHub Desktop.
Aligning two ggplots when one has a legend
## Function to align two ggplot objects when 1 has a legend and one doesn't
## Copied from https://stackoverflow.com/a/30414008/1710632 on 2018-02-08
AlignPlots <- function(...) {
LegendWidth <- function(x) x$grobs[[8]]$grobs[[1]]$widths[[4]]
plots.grobs <- lapply(list(...), ggplotGrob)
max.widths <- do.call(unit.pmax, lapply(plots.grobs, "[[", "widths"))
plots.grobs.eq.widths <- lapply(plots.grobs, function(x) {
x$widths <- max.widths
x
})
legends.widths <- lapply(plots.grobs, LegendWidth)
max.legends.width <- do.call(max, legends.widths)
plots.grobs.eq.widths.aligned <- lapply(plots.grobs.eq.widths, function(x) {
if (is.gtable(x$grobs[[8]])) {
x$grobs[[8]] <- gtable_add_cols(x$grobs[[8]],
unit(abs(diff(c(LegendWidth(x),
max.legends.width))),
"mm"))
}
x
})
plots.grobs.eq.widths.aligned
}
## EXAMPLE BELOW
library(ggplot2)
library(gtable)
library(gridExtra)
df <- data.frame(x = c(1:5, 1:5),
y = c(1:5, seq.int(5,1)),
type = factor(c(rep_len("t1", 5), rep_len("t2", 5))))
p1.1 <- ggplot(diamonds, aes(clarity, fill = cut)) + geom_bar()
p1.2 <- ggplot(df, aes(x = x, y = y, colour = type)) + geom_line()
plots1 <- AlignPlots(p1.1, p1.2)
do.call(grid.arrange, plots1)
p2.1 <- ggplot(diamonds, aes(clarity, fill = cut)) + geom_bar()
p2.2 <- ggplot(df, aes(x = x, y = y)) + geom_line()
plots2 <- AlignPlots(p2.1, p2.2)
do.call(grid.arrange, plots2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment