Home > Software design >  assigning different labels to each row of a facet with label_bquote
assigning different labels to each row of a facet with label_bquote

Time:09-22

I have some troubles in assigning different labels to a facet strip using label_bquote.

mpg$class2 <- reorder(mpg$class, mpg$displ)
ggplot(mpg, aes(displ, hwy))  
    geom_point()  
    facet_wrap( ~ class2, ncol = 1, scales="free_y",
               strip.position = "left",
               labeller = label_bquote(rows  = list("2S"[e]~(sigma ~m^-3), sigma[U], three, for, five, six, psi)) )

where the final result is that I have all 7 labels in all 7 rows. I tried with list, but it did not help.

Thanks,

A

enter image description here

CodePudding user response:

This approach creates a label variable which is used to facet the data and provide the plotmath expression for the strip label.

library(ggplot2)

# data frame mapping the unique `class` values to the required mathplot expression

df_labs <- data.frame(class = c("compact",  "subcompact", "midsize" ,  "minivan", "pickup", "suv", "2seater"),
                      class2 = c("2*S[e]~(sigma ~m^{-3})","sigma[U]", "three", "four", "five", "six", "psi"))

mpg <- merge(mpg, df_labs)

mpg$class2 <- reorder(mpg$class2, mpg$displ)


ggplot(mpg, aes(displ, hwy))  
  geom_point()  
  facet_wrap(~class2,
              ncol = 1,
              scales="free_y",
              strip.position = "left",
              labeller = label_parsed)

Created on 2021-09-17 by the reprex package (v2.0.0)

CodePudding user response:

The label_bquote function is only really helpful if you want to build an expression using the current value for the faceting variable. Since you want to build an entirely different expression that doesn't use the values of "pickup", "suv", etc, that's not going to be very helpful.

First I would suggest you make a clear mapping from the faceting variable to the label you want to use. For example

strip_labels <- expression(
  compact = "2S"[e]~(sigma ~m^-3),
  subcompact = sigma[U],
  midsize = three,
  minivan = four,
  pickup = five,
  suv = six,
  "2seater" = psi
)

Then we can use a helper function to pluck values from this expression list. Here's that function

label_expressions <- function(values) {
  stopifnot(is.expression(values))
  as_labeller(function(x) {
    if (is.null(names(values))) {
      x <- seq_along(x)
      if (length(x)!=length(values)) warning(paste0("Number of labels(", 
        length(values), ") does not match number of values (", length(x), ")"))
    }
    as.list(values[x])
  }, default=identity)
}

Then we can use that helper with the labeller function to relabel the faceting variable

ggplot(mpg, aes(displ, hwy))  
  geom_point()  
  facet_wrap( ~class2, ncol = 1, scales="free_y",
              strip.position = "left",
              labeller  = labeller(class2 = label_expressions(strip_labels)))

This methods keeps the expression values rather that forcing your to coerce to character values and then re-parse the values. It doesn't change your actual data at all.

With this helper, you can pass an unnamed expression directly if you like as well

ggplot(mpg, aes(displ, hwy))  
  geom_point()  
facet_wrap( ~ class2, ncol = 1, scales="free_y",
               strip.position = "left",
               labeller = labeller(class2 = label_expressions(expression("2S"[e]~(sigma ~m^-3), sigma[U], three, four, five, six, psi))))
  • Related