7

Which property, if any, in ggplot controls
the width (or amount of blank space) of the axis text?


In the example below, my ultimate goal is to "push in" the left-hand side of the top graph so that it lines up with the bottom graph.

I tried theme(plot.margin=..) but that affects the margin of the entire plot.
facet'ing doesn't help either, since the scales on the y are different.

As a last resort, I realize I could modify the axis text itself, but then I would also need to calculate the cuts for each graph.

enter image description here

Reproducible Example:

library(ggplot2)
library(scales)

D <- data.frame(x=LETTERS[1:5],  y1=1:5, y2=1:5 * 10^6)

P.base <- ggplot(data=D, aes(x=x)) + 
            scale_y_continuous(labels=comma)

Plots <- list(
    short = P.base + geom_bar(aes(y=y1), stat="identity", width=.5)
  , long  = P.base + geom_bar(aes(y=y2), stat="identity", width=.5) 
  )

do.call(grid.arrange, c(Plots, ncol=1, main="Sample Plots"))
Ricardo Saporta
  • 54,400
  • 17
  • 144
  • 178
  • 1
    `grid.arrange` is no good at aligning plots, you should always use gtable for this. – baptiste Mar 10 '14 at 12:27
  • 1
    Thanks @baptiste, that seems to be exactly what I was looking for. Feel free to post a your own answer. Also, I'm curious why `rbind_gtable` is not an exported function? – Ricardo Saporta Mar 11 '14 at 04:43
  • 1
    `rbind.gtable` is exported as a method, but it calls this function with Reduce for multiple gtables. Either that, or hadley has a weakness for underscores. – baptiste Mar 11 '14 at 10:37

1 Answers1

9

Here is one solution.

The idea was borrowed from "Having horizontal instead of vertical labels on 2x1 facets and splitting y-label Define a function

align_plots1 <- function (...) {
    pl <- list(...)
    stopifnot(do.call(all, lapply(pl, inherits, "gg")))
    gl <- lapply(pl, ggplotGrob)
    bind2 <- function(x, y) gtable:::rbind_gtable(x, y, "first")
    combined <- Reduce(bind2, gl[-1], gl[[1]])
    wl <- lapply(gl, "[[", "widths")
    combined$widths <- do.call(grid::unit.pmax, wl)
    grid::grid.newpage()
    grid::grid.draw(combined)
}

short <- P.base + geom_bar(aes(y=y1), stat="identity", width=.5)
long <- P.base + geom_bar(aes(y=y2), stat="identity", width=.5) 

#Now, align the plots
align_plots1(short, long)

Here is the output.

enter image description here

Community
  • 1
  • 1
Jd Baba
  • 5,948
  • 18
  • 62
  • 96
  • 2
    it's useful and good etiquette to link to the original question when you borrow a solution from somewhere else. – baptiste Mar 10 '14 at 12:25
  • Thanks for reminding. I forgot to attach the link where I found that solution. I added the link. – Jd Baba Mar 10 '14 at 16:48