18
votes

I am using facet_wrap to split my scatter plot as

facet_wrap(x~y+z)

This generates 22 plots in my case as desired. However, label for each of those 22 plots is displayed in 3 rows (x, y and z) which unnecessarily consumes the space in the window and squishes the plots into a small area. I would rather want my plots to be bigger in size. Since variables y and z are short, I would like to display them in same row instead of two.

I looked into the labeller options but none of them seem to do what I would want. I would appreciate any suggestions here.

2

2 Answers

27
votes

In this case you might also consider label_wrap_gen():

p <- ggplot(mtcars, aes(wt,mpg)) + geom_point() 
p + facet_wrap(cyl~am+vs, labeller = label_wrap_gen(multi_line=FALSE))

For more details see also here and here.

10
votes

I'm not sure how to do this with a labeller function, but another option is to create a grouping variable that combines all three of your categorical variables into a single variable that can be used for faceting. Here's an example using the built-in mtcars data frame and the dplyr package for creating the new grouping variable on the fly. Following that is an update with a function that allows dynamic choice of from one to three faceting variables.

library(dplyr)

ggplot(mtcars %>% mutate(group = paste(cyl,am,vs, sep="-")), 
       aes(wt,mpg)) +
  geom_point() +
  facet_wrap(~group)

enter image description here

UPDATE: Regarding the comment about flexibility, the code below is a function that allows the user to enter the desired data frame and variable names, including dynamically choosing to facet on one, two, or three columns.

library(dplyr)
library(lazyeval)

mygg = function(dat, v1, v2, f1, f2=NA, f3=NA) {

  dat = dat %>% 
    mutate_(group = 
              if (is.na(f2)) {
                f1
              } else if (is.na(f3)) {
                interp(~paste(f1,f2, sep='-'), f1=as.name(f1), f2=as.name(f2))
              } else {
                interp(~paste(f1,f2,f3,sep='-'), f1=as.name(f1), f2=as.name(f2), f3=as.name(f3))
              })

  ggplot(dat, aes_string(v1,v2)) +
    geom_point() +
    facet_wrap(~group)
}

Now let's try out the function:

library(vcd) # For Arthitis data frame

mygg(Arthritis, "ID","Age","Sex","Treatment","Improved")
mygg(mtcars, "wt","mpg","cyl","am")
mygg(iris, "Petal.Width","Petal.Length","Species")

enter image description here