2

I wish to plot a number of tightly spaced graphs as illustrated by the following toy example:

library(ggplot2)
library(gridExtra)
set.seed(314159)
n <- 100
data <- data.frame(x = rnorm(n), y = rnorm(n), z = rep("dummy var", n))

p00 <- ggplot(data, aes(x)) + stat_density() + theme(plot.margin = unit(c(0,0,0,0), units = "lines" ), axis.text = element_blank(), axis.title = element_blank(), axis.ticks = element_blank()) + labs(x = NULL, y = NULL)
p01 <- ggplot(data, aes(x, y)) + geom_point() + theme(plot.margin = unit(c(0,0,0,0), units = "lines" ), axis.text = element_blank(), axis.title = element_blank(), axis.ticks = element_blank()) + labs(x = NULL, y = NULL)
p10 <- ggplot(data, aes(y, x)) + geom_point() + theme(plot.margin = unit(c(0,0,0,0), units = "lines" ), axis.text = element_blank(), axis.title = element_blank(), axis.ticks = element_blank()) + labs(x = NULL, y = NULL)
p11 <- ggplot(data, aes(y)) + stat_density() + theme(plot.margin = unit(c(0,0,0,0), units = "lines" ), axis.text = element_blank(), axis.title = element_blank(), axis.ticks = element_blank()) + labs(x = NULL, y = NULL)

grid.arrange(p00, p01, p10, p11, ncol = 2)

In spite of my best efforts, I have been unable to overcome a complication that arises when I attempt to do so after having removed the facet strips from my graphs. In the following example, I have added horizontal and vertical strips to each graph by faceting on a dummy variable:

p00 <- p00 + facet_grid(z ~ z)
p01 <- p01 + facet_grid(z ~ z)
p10 <- p10 + facet_grid(z ~ z)
p11 <- p11 + facet_grid(z ~ z)

grid.arrange(p00, p01, p10, p11, ncol = 2)

Next I remove the strips according to the procedure outlined in this post. However, the resulting graphs are rather widely spaced by comparison:

p00 <- p00 + theme(plot.margin = unit(c(0,0.5,0.5,0), units = "lines" ), strip.background = element_blank(), strip.text = element_blank())
p01 <- p01 + theme(plot.margin = unit(c(0,0.5,0.5,0), units = "lines" ), strip.background = element_blank(), strip.text = element_blank())
p10 <- p10 + theme(plot.margin = unit(c(0,0.5,0.5,0), units = "lines" ), strip.background = element_blank(), strip.text = element_blank())
p11 <- p11 + theme(plot.margin = unit(c(0,0.5,0.5,0), units = "lines" ), strip.background = element_blank(), strip.text = element_blank())

grid.arrange(p00, p01, p10, p11, ncol = 2)

Any suggestions on how to reduce the spacing between graphs would be much appreciated.

Community
  • 1
  • 1
Paul S
  • 33
  • 5

1 Answers1

1

To remove all elements associated with the axes, in addition to the elements you have set to element_blank, the tick margins and tick lengths need to be set to zero. But space will remain for the facet strips. Setting the background and text to element_blank does not affect the height and width of the strips. To remove the strips, I use functions that manipulate the gtable layout. However, I think it is better to leave some white space between the plots. I have set a small plot margin to 0.2 lines.

library(ggplot2)
library(gridExtra)
set.seed(314159)
n <- 100
data <- data.frame(x = rnorm(n), y = rnorm(n), z1 = rep("dummy var", n), z2 = rep("dummy var", n))

theme = theme(plot.margin = unit(c(.2,.2,.2,.2), units = "lines"), 
         axis.text = element_blank(), 
         axis.title = element_blank(), 
         axis.ticks = element_blank(), 
         axis.ticks.length = unit(0, "lines"))
labs = labs(x = NULL, y = NULL) 

p00 <- ggplot(data, aes(x)) + stat_density() + theme + labs + facet_grid(z1 ~ z2)
p01 <- ggplot(data, aes(x, y)) + geom_point() + theme + labs + facet_grid(z1 ~ z2)
p10 <- ggplot(data, aes(y, x)) + geom_point() + theme + labs + facet_grid(z1 ~ z2)
p11 <- ggplot(data, aes(y)) + stat_density() + theme + labs + facet_grid(z1 ~ z2)

This is where the gtable layout is manipulated.

# Get the four gtables (and the four plots) into a list
pList = list(p00, p01, p10, p11)
gList = lapply(pList, ggplotGrob)

# Remove the top strip from each plot
stripT <- subset(gList[[1]]$layout, grepl("strip-t", gList[[1]]$layout$name))
gList = lapply(gList, function(x) x[-stripT$t, ])

# Remove the right strip from each plot
stripR <- subset(gList[[1]]$layout, grepl("strip-r", gList[[1]]$layout$name))
gList = lapply(gList, function(x) x[, -stripR$r])

# Draw the revised plots
nCol <- floor(sqrt(length(pList)))
do.call(grid.arrange, c(gList, ncol = nCol))

enter image description here

Edit: Using revised data and plot.

library(grid)

data <- data.frame(x = rnorm(n), y = rnorm(n), z = rep("dummy var", n), u = seq(1, n) %% 2) 
p01 <- ggplot(data, aes(x, y)) + geom_point() + theme + labs + facet_grid(z ~ u)

g = ggplotGrob(p01)
stripT = subset(g$layout, grepl("strip-t", g$layout$name))
g = g[-stripT$t, ]
stripR = subset(g$layout, grepl("strip-r", g$layout$name))
g = g[, -stripR$r]

grid.draw(g) # Still got the space between the facets

g$widths  # where is the space? it's the 5.55 pt width

g$widths[[5]] = unit(0, "lines") # remove it completely
g$width
grid.draw(g)
Sandy Muspratt
  • 31,719
  • 12
  • 116
  • 122
  • Many thanks! It works perfectly for the toy example. I noticed that vertical strips remain in the more general case when we have: `data <- data.frame(x = rnorm(n), y = rnorm(n), z = rep("dummy var", n), u = seq(1, n) %% 2)` and `p01 <- ggplot(data, aes(x, y)) + geom_point() + theme + labs + facet_grid(z ~ u)` with all else being the same as in your solution. My initial efforts to make it work by modifying your code ended in failure, but I'll post the answer, should I get it working. – Paul S Jan 30 '15 at 07:25
  • Yes, in your revised data and plot, there is a built in space between the two facets. See an edit to remove that space. – Sandy Muspratt Jan 30 '15 at 08:06