6

Is it possible to have independent strip themes for each variable used in ggplot2 facet_wrap?

Take this chunk of code as an example:

p1 <- ggplot(mpg, aes(displ, hwy)) +
   geom_point() +
   facet_wrap(c("cyl", "drv"), labeller = "label_both")
plot(p1)

Plot output

I would want to have upper strip ('cyl') with a different theme - say, in bold. Additionally, I might want to make 'drv' italic and with a different font type and size. How could I do that?

I was thinking something in the lines of:

 p1 <- p1 + theme(strip.text.variable1 = element_text(face = 'bold'),
                  strip.text.variable2 = element_text(face = 'italic', size = 8)
                  )

Unfortunately, I couldn't find anything like this in the docs or previous questions.

Cheers

Edit: I made the question a bit more general to be of further help to the community.

Ricardo A.
  • 156
  • 8
  • 2
    [How to use different font sizes in ggplot facet wrap labels?](http://stackoverflow.com/questions/36334486/how-to-use-different-font-sizes-in-ggplot-facet-wrap-labels) seems relevant. – Henrik Aug 26 '16 at 17:08

1 Answers1

4

Ostensibly you should be able to make a new function based on label_both to return bold labels, but so far my attempts have ended with the dreaded Error in variable[[i]] : subscript out of bounds.

An alternative to this is to build a function to make the label you want. This is much like this answer. In this function you add the prefix to the values of the variable and make them bold.

make_labels = function(string, prefix = "cyl: ") {
    x = paste0(prefix, as.character(string))
    do.call(expression, lapply(x, function(y) bquote(bold(.(y)))))
}

Now use this function within as_labeller for the "cyl" variable in facet_wrap. You want to change the default labeller within as_labeller to label_parsed so the expression is parsed correctly. Use label_both for the other variable.

ggplot(mpg, aes(displ, hwy)) +
    geom_point() +
    facet_wrap(c("cyl", "drv"), 
               labeller = labeller(cyl = as_labeller(make_labels, default = label_parsed), 
                                   drv = label_both))

enter image description here

Community
  • 1
  • 1
aosmith
  • 34,856
  • 9
  • 84
  • 118
  • That's definitely one way out, thanks. However, I'm stuck with using the `label_both` parameter for "cyl" in order to anchor the `prefix = "cyl: "` call. It would also be interesting to use this function free of constraints (e.g. with `label_value`, instead). – Ricardo A. Aug 26 '16 at 19:24
  • I agree that it would be nice to not hard-code the labeller to your particular variable (although you don't have to use `"cyl: "`, use whatever your variable name is instead). I don't quite follow your second sentence, as the function I wrote is specifically meant to be used with `label_parsed` in order use `bold`. – aosmith Aug 26 '16 at 19:38
  • Yes, I meant `"cyl: "` only as an example (in my case is `"method: "`). Sorry if I wasn't clear about the second sentence. What I meant to say is that this solution only works if we explicitly put the name of the variable in the function (and it gets included in the strip itself) - it would be good for it to work if I didn't want "cyl: 4", "cyl: 5", "cyl 6", "cyl: 8" in the strip text, just "4", "5", "6", and "8". – Ricardo A. Aug 26 '16 at 19:55
  • 1
    Make a labeling function without the `prefix` argument to have bold labels of the values. The main difference would be that `x = paste0(...)` would change to `x = as.character(string)`. – aosmith Aug 26 '16 at 20:00