0

I am trying to create a graph panel with 8 graphs in total ( 4 x 4). Each graph corresponds to a different gene, whereby there are three lines ( one for control, one for UC disease and one for Crohns), representing the average change in expression comparing a first measurement and a second.

The code I am using to run each of the plots is;

s <- ggplot(X876, aes(x=Timepoint, y=value, group=Group)) +
  geom_line(aes(color=Group), size=1)+
  geom_point(aes(color=Group), size=2.5) + 
  labs(y="X876") + ylim(0.35, 0.55) + 
  theme_classic() + 
  scale_color_manual(values=c("darkmagenta", "deepskyblue4", "dimgrey"))

Using grid.arrange(l, m, n, o, p, q, r, s, nrow=4, nrow=4), creates a graph panel where the y axes names overlap.

I have seen on here about changing the plot margins via,

  pl = replicate(3, ggplot(), FALSE)
  grid.arrange(grobs = pl)

  margin = theme(plot.margin = unit(c(2,2,2,2), "cm"))
  grid.arrange(grobs = lapply(pl, "+", margin))

However, I am unsure how this can be applied to increase the vertical height between the plots on the top and bottom rows. For each of the graphs l, m, n, o, p, q, r, s do I need to include

   + theme(plot.margin=unit(c(t,r,b,l),"cm"))

and then run the grid.arrange(l, m, n, o, p, q, r, s, nrow=4, ncol=4)

Please could somebody suggest which values do I need to include for top (t), right(r), bottom (b), left(l) to only increase the distance (by about 3cms) between the top and bottom row? I am trying different values and I'm not getting a decent graph panel yet.

Thank-you

teunbrand
  • 33,645
  • 4
  • 37
  • 63
jaria20
  • 61
  • 7
  • "[How] to only increase the distance ... between the top and bottom row?" That's not clear to me. It suggests you want the top and bottom rows to be further apart - away from each other. Or do you want to increase the top and bottom plot margins (which will effectively _reduce_ the distance between the top and bottom rows!)? Can you provide a reproducible example? – Edward Apr 13 '20 at 00:35

2 Answers2

1

Probably the easiest way is to create your own theme based on the theme_classic theme and then modify the plotting margins (and anything else) the way that you prefer.

theme_new <- theme_classic() + 
  theme(plot.margin=unit(c(1,0,1,0), "cm")) # t,r,b,l

Then set the theme (will revert back to the default on starting a new R session).

theme_set(theme_new)

The alternative is to use grid.arrange and modify the margins using the grobs as you've already mentioned.

Once the panels have been arranged, you can then modify the top and bottom margins (or left and right) by specifying the vp argument of grid.arrange, which allows you to modify the viewport of multiple grobs on a single page. You can specify the height and width using the viewport function from the grid package.

For example, if you have a list of ggplot() grobs called g.list that contain your individual plots (l,m,n,o,p,q,r,s), then the following would reduce the height of the viewport by 90%, which effectively increases the top and bottom margins equally by 5%.

library(grid)
library(gridExtra)

grid.arrange(grobs = g.list, vp=viewport(height=0.9))

Without your data, I can't test it, especially to see if the y-axes labels overlap. And I don't know why you think increasing the top and bottom margins can solve that problem since the y-axes are, by default, on the left-hand side of the graph.

Anyway, I'll use the txhousing dataset from the ggplot2 package to see if I can reproduce your problem.

library(ggplot2)
data(txhousing)

theme_new <- theme_classic() + 
   theme(plot.margin=unit(c(0.1,0.1,0.1,0.1), "cm"), text=element_text(size=8))

theme_set(theme_new)

tx.list <- split(txhousing, txhousing$year)

g.list <- lapply(tx.list, function(data) 
{
  ggplot(data, aes(x=listings, y=sales)) +
    geom_point(size=0.5)
} )

grid.arrange(grobs = g.list, vp=viewport(height=0.9))

enter image description here

I don't see any overlapping. And I don't see why increasing the top and bottom margins would make much difference.

Edward
  • 10,360
  • 2
  • 11
  • 26
  • Thank-you for your help here, and I am sorry I didn't make my question above clearer. Using the vp=viewport(height=0.9) has worked very well. – jaria20 Apr 13 '20 at 14:24
0

The question was asked a couple of years ago, but I bumped into it only now and thought that I might share a quick and dirty tip for this, which works good enough in many cases.

In some situations the theme is already so complex that this trick might be the easiest way: adding a few \n's (newlines) to the x and y axis names, as this will affect the distances between the plots in the panel. I've learned this trick for a slightly different purpose from here (originally from here).

I'll use the same logic for the example dataset (in this case: Orange from R built-in data sets) as in the excellent code by the previous answerer.

library(ggplot2)
library(gridExtra)

or.list <- split(Orange, Orange$Tree)

g.list <- lapply(or.list, function(data) 
{
  ggplot(data, aes(x=age, y=circumference)) +
    theme_classic() +
    geom_point(size=0.5) +
    scale_x_continuous(name = "Age\n\n") +
    scale_y_continuous(name = "\n\n\nCircumference")
} )

grid.arrange(grobs = g.list)

An image where the distance between the plots is controlled with \n's in the axis names

jaggedjava
  • 440
  • 6
  • 14