How to place the strip in facet_grid on top of plots when plotting graphs vertically stacked - similar to position.strip = "top" in facet_wrap?

Viewed 658

Using facet_grid(), how can I place the group names, i.e. the grey strips, on the top of the plots when graphing the plots stacked vertically in a single column?

From what I have tried, when stacking the plots vertically, using facet_grid(), you cannot place the strip on the top or bottom of the graph; you can only place the strip on the right hand side or the left hand side of the plots using the switch = c("y", "x", "both") argument.

I am aware that facet_wrap() (and facet_col() from ggforce) can place the strip anywhere using the strip.position = c("top", "bottom", "left", "right") argument, irrespective of how the graphs are being plotted: vertically or horizontally. I used facet_wrap() to produce Fig.1 below (code is in the Reproducible Code section).

However, I would like to be able to produce the plot below (with the strip on "top") using facet_grid() not facet_wrap.

Fig.1: I want to be able to plot this using facet_grid()

Fig.1

Ideally, it would be great if the switch argument could be extended or the strip.position argument could be added to facet_grid(), to be able to place the strip on top. I tried to do it myself by trying to change the source code from facet_grid() and facet_wrap() functions, but could not figure it out.

The reason I am not simply using facet_wrap() function is because it unfortunately does not have the space="free" argument which is available in facet_grid() and is essential in my application.

Below is a reproducible example taken from, with slight modifications, the code of Brandon Bertelsen answer's here:

Reproducible Code:

The Data:

dat <- data.frame(value=runif(30)*10,
                  grouping=c(rep("Group 1",10),
                             rep("Group 2",10),
                             rep("Group 3",10)),
                  letters=rep(LETTERS[1:10], 3)

Using facet_wrap to get strip on top when plotting graphs vertically:

ggplot(dat, aes(letters,value, label = letters)) + 
  geom_bar(stat="identity") + 
  facet_wrap(grouping~., dir = "v")

Produces Fig.1:

Fig.1:

Using facet_grid with the switch = "y" places the strip to the left hand side:

ggplot(dat, aes(letters,value, label = letters)) + 
  geom_bar(stat="identity") + 
  facet_grid(grouping~., switch = "y")

Produces Fig.2:

Fig.2

Using facet_grid with the switch = "x" places the strip to the right hand side:

ggplot(dat, aes(letters,value, label = letters)) + 
     geom_bar(stat="identity") + 
     facet_grid(grouping~., switch = "x")

Produces Fig.3:

Fig.3

With no other options remaining I turn here for help.

1 Answers

Is that what you want? Then just leave sales = 'free' out.

library(ggplot2)

dat <- data.frame(value=runif(26)*10,
                  grouping=c(rep("Group 1",10),
                             rep("Group 2",10),
                             rep("Group 3",6)),
                  letters=LETTERS[1:26])

ggplot(dat, aes(letters,value, label = letters)) + 
  geom_bar(stat="identity") + 
  facet_wrap(grouping~., dir = "v")

Created on 2020-06-13 by the reprex package (v0.3.0)

Related