Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In ggplot2 and facet_wrap, how to remove all margins and padding yet keep strip.text?

This might primarily be a result of me misunderstanding how panel.margin = unit(...) works in the theme() function...but I'm unable to customize margins in facet_wrap the way that I'd like. Basically, I want a facet_grid that looks like this, with facet text (i.e. strip.text) inset in each facet and no spcaing between each facet:

(I've left in the pink borders to show the dimensions of each facet)

The ideal final product

So here's the code so far.

To set up the data and plot:

library(ggplot2)
library(grid)
p <- ggplot() +
  geom_bar(data = mtcars, aes(x = cyl, y = qsec), stat = 'identity') +
  facet_wrap( ~ carb, ncol = 3)

mytheme <- theme_minimal() + theme(
  axis.text.x = element_blank(),
  axis.text.y = element_blank(),
  axis.ticks = element_blank(),
  axis.title = element_blank(),
  panel.margin = unit(0, "lines"),
  panel.border = element_rect(colour = rgb(1.0, 0, 0, 0.5), fill=NA, size=1)
)
The standard plot
 p + mytheme

just a standard plot

Removing the strip.text completely
p + mytheme + theme(strip.text = element_blank())

no strip text

Adding the strip.text and insetting it
p + mytheme +
     theme(strip.text = element_text(size = rel(3.0), vjust = -4.0))

test grid inset text

The re-inclusion of strip.text (and the increased relative size) increases the vertical margin between the two rows. So at this point, I don't know how to close the vertical gap between the top and bottom rows.

Too much negative margin
p + mytheme +
    theme(strip.text = element_text(size = rel(3.0), vjust = -4.0), 
          panel.margin = unit(c(-2, -2), "lines"))

Too much negative margin

So how do I target just the panel.margin between the two rows?

Edit: Additional information. The space between the rows appears to be strip.background:

p + mytheme +
        theme(strip.text = element_text(size = rel(3.0), vjust = -4.0),
              panel.margin = unit(-1, "lines"),
              strip.background = element_rect(fill = rgb(0, 1.0, 0, 0.2)))

enter image description here

like image 939
dancow Avatar asked Sep 06 '15 18:09

dancow


1 Answers

Among the list of possible arguments to theme(), there is not only panel.margin ("margin around facet panels (unit)", see ?theme), but conveniently, you can also access one of the axes at a time, with panel.margin.x and panel.margin.y respectively ("horizontal/vertical margin around facet panels (unit; inherits from panel.margin)").

Therefore, while decreasing the margin below zero feels a bit like a hack, something like the following will do the job (you might have to adjust the value a little - unit(-2, "lines") worked best for me):

p + theme(strip.text = element_text(size = rel(3.0), vjust = -4.0), 
          panel.margin.y = unit(-2, "lines"))

If you use strip.text = element_blank(), then you should probably use panel.margin.y = unit(-0.5, "lines").

like image 131
maj Avatar answered Oct 08 '22 18:10

maj