A.Benson
A.Benson

Reputation: 479

Using formulae on facet_wrap in ggplot2

I'm trying to replace the facet_wrap titles on a ggplot bar plot with expressions, but I'm having no luck. I've tried here and here but neither seem to be working for me.

The whole dataset is quite large, so here's some dummy data to illustrate the problem.

library(tidyr)
library(ggplot2)

    data<-data.frame(species = rep(c("oak", "elm", "ash"), each = 5),
resp_1 = (runif(15, 1,100)),
resp_2 = (runif(15, 1,100)),
resp_3 = (runif(15, 1,100)),
resp_4 = (runif(15, 1,100)),
resp_5 = (runif(15, 1,100)))

### transform to longform with tidyr

data_2 <- gather(data, response, result, resp_1:resp_5, factor_key=TRUE)

### plot with ggplot2

ggplot(data_2, aes(x = species, y = result, fill = species))+
  geom_bar(stat = 'sum')+
  facet_wrap(~ response)

### here are the labels I'd like to see on the facets

oxygen <-expression ("Oxygen production (kg/yr)")
runoff <-expression("Avoided runoff " ~ (m ^{3} /yr))
co <- expression("CO removal (g/yr)")
o3 <- expression("O"[3]~" removal (g/yr)")
no2 <- expression("NO"[2]~" removal (g/yr)")

labels <- c(oxygen, runoff, co, o3, no2)

### this doesn't work 

ggplot(data_2, aes(x = species, y = result, fill = species))+
  geom_bar(stat = 'sum')+
  facet_wrap(~ response, labeller = labeller(response = labels))

![enter image description here

### close, but doesn't work

levels(data_2$response)<-labels


ggplot(data_2, aes(x = species, y = result, fill = species))+
  geom_bar(stat = 'sum')+
  facet_wrap(~ response, labeller = labeller(response = labels))

![enter image description here

### produces an error

ggplot(data_2, aes(x = species, y = result, fill = species))+
  geom_bar(stat = 'sum')+
  facet_wrap(~ response, labeller = label_parsed)

I'd also like to get rid of the second legend in grey titled "n".

Upvotes: 3

Views: 420

Answers (2)

Tung
Tung

Reputation: 28381

Use as_labeller and label_parsed. Ref

library(tidyr)
library(ggplot2)

data <- data.frame(species = rep(c("oak", "elm", "ash"), each = 5),
                   resp_1 = (runif(15, 1, 100)),
                   resp_2 = (runif(15, 1, 100)),
                   resp_3 = (runif(15, 1, 100)),
                   resp_4 = (runif(15, 1, 100)),
                   resp_5 = (runif(15, 1, 100)))
data_2 <- gather(data, response, result, resp_1:resp_5, factor_key = TRUE)

# setup the labels
reponse_names <- c(
  `resp_1` = "Oxygen~production~(kg*yr^{-1})",
  `resp_2` = "Avoided~runoff~(m^{3}*yr^{-1})",
  `resp_3` = "CO~removal~(g*yr^{-1})",
  `resp_4` = "O[3]~removal~(g*yr^{-1})",
  `resp_5` = "NO[2]~removal~(g*yr^{-1})"
)

# plot
ggplot(data_2, aes(x = species, y = result, fill = species))+
  geom_bar(stat = 'sum')+
  facet_wrap(
    ~ response,
    labeller = labeller(response  = as_labeller(reponse_names,  label_parsed))
  ) +
  guides(size = "none")

Created on 2021-04-30 by the reprex package (v2.0.0)

Upvotes: 4

MrFlick
MrFlick

Reputation: 206253

Right now your expression names don't match up to the values used as the facets. So I'd recommend storing your labels in an expression

labels <- expression(
  resp_1 = "Oxygen production (kg/yr)",
  resp_2 = "Avoided runoff " ~ (m ^{3} /yr),
  resp_3 = "CO removal (g/yr)",
  resp_4 = "O"[3]~" removal (g/yr)",
  resp_5 = "NO"[2]~" removal (g/yr)"
)

And then you can write your own labeler function to extract the correct value

ggplot(data_2, aes(x = species, y = result, fill = species))+
  geom_bar(stat = 'sum', show.legend = c(size=FALSE))+
  facet_wrap(~ response, labeller = function(x) {
    list(as.list(labels)[x$response])
  })

facet grid with expressions

We've also used show.legend = c(size=FALSE) to turn off the n legend

Upvotes: 5

Related Questions