1

I have seen many solutions for aligning the plotting regions of ggplot2 plots. However, I have a couple of plots that have been made by a function that outputs a result from arrangeGrob. I would like to plot them in a column, with both the beginning and end of the x-axis aligned. Here is a runnable example of what happens.

To run the example,

library(ggplot2)
library(gridExtra)

topPlot <- f(TRUE, TRUE, TRUE, "Dataset 1")
bottomPlot <- f(FALSE, FALSE, FALSE, "Dataset 2")
grid.draw(arrangeGrob(topPlot, bottomPlot, nrow = 2))

The definition of f :

f <- function(x,y, z, t)
{
  showLegends = x
  knownClasses <- rep(c("Healthy", "Sick"), each = 5)
  plotData <- data.frame(name = LETTERS[1:10],
                     type = rep(c("Method 1", "Method 2"), each = 10),
                     class = rep(c("Healthy", "Sick"), each = 5),
                     Error = runif(20))

  classesPlot <- ggplot(data.frame(Class = knownClasses), aes(1:length(knownClasses), factor(1)), environment = environment()) +
             geom_tile(aes(fill = Class, height = 10)) +
             scale_x_discrete(expand = c(0, 0), breaks = NULL, limits = c(1, length(knownClasses))) +
             scale_y_discrete(expand = c(0, 0), breaks = NULL) +
             labs(x = '', y = '')+ theme(legend.position = ifelse(showLegends, "right", "none"))

  errorPlot <- ggplot(plotData, aes(name, type)) + geom_tile(aes(fill = Error)) + theme_bw() +
           theme(legend.position = ifelse(showLegends, "right", "none"),
          axis.text.y = if(y) element_text(size = 8) else element_blank()) + ylab(if(z) "Label" else NULL)

  classGrob <- ggplot_gtable(ggplot_build(classesPlot))
  errorGrob <- ggplot_gtable(ggplot_build(errorPlot))
  commonWidth <- unit.pmax(classGrob[["widths"]], errorGrob[["widths"]])
  classGrob[["widths"]] <- commonWidth
  errorGrob[["widths"]] <- commonWidth

  arrangeGrob(classGrob, errorGrob, nrow = 2, heights = c(1, 3), main = t)
}

In a real scenario, the two datasets will have different samples in different proportions of classes, so getting rid of the class colour scale above each error plot is not an option, unless multiple colour scales per plot were allowed in ggplot2.

How can this code be modified to align the plot areas ?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Dario
  • 371
  • 1
  • 3
  • 13
  • Google for examples of arrangeGrob with legend stacked vertically, like this [link](http://stackoverflow.com/questions/16963137/ggplot2-multiple-plots-with-different-variables-in-a-single-row-single-groupin). You need a function to pull the legend out of ggplot, and then put it back in. –  Oct 22 '14 at 04:49
  • I understand the approach you suggest. However, I would like to keep the function simple, so that it makes a plot for a single dataset. Is there a simpler modification of the `topPlot` and `bottomPlot` objects ? – Dario Oct 22 '14 at 06:00
  • For the case with legends, make the plots with the legends, then extract the legend, and plot the plot and legend with fixed widths, ie cm. For the case without legends, you can make the plot without the legend then put in a grob with a fixed width. Then stack the grobs. In the main routine, you will need to left alight the grobs so the bottom plot doesn't come out centered. –  Oct 22 '14 at 13:23

0 Answers0