user2165907
user2165907

Reputation: 1451

use of bquote in ggplot2 custom labeller

Is it possible to properly use bquote in some instances of ggplot2 custom labellers? The following example does not produce the desired output (and does not show any warning/error):

library(ggplot2)
data(Orange)
Orange$tree2 <- paste0("T", Orange$Tree)

tree.lab <- c(
  T1 = bquote("Tree 1"[test]), 
  T2 = "Tree 2", 
  T3 = "Tree 3",  
  T4 = "Tree 4", 
  T5 = "Tree 5"
)

ggplot(Orange, aes(x = age, y = circumference)) +
  facet_wrap(~tree2, labeller = labeller(tree2 = tree.lab)) +
  geom_point()

The following old style code still works but is deprecated (ggplot2 version 3.3.5 warns "Warning message: The labeller API has been updated. Labellers taking variable and value arguments are now deprecated. See labellers documentation."):

vlabeller <- function (variable, value) {
  return(tree.lab[value])
}

ggplot(Orange, aes(x = age, y = circumference)) +
  facet_wrap(~tree2, labeller = vlabeller) +
  geom_point()

What would be a proper way to do that nowadays? Even without bquote...

Upvotes: 0

Views: 307

Answers (1)

MrFlick
MrFlick

Reputation: 206167

Basically with your list, you would want to update the vlabeller to use the as_labeller function. The default=identity prevents the expressions from being coerced back into text.

vlabeller <- as_labeller(function (value) {
  tree.lab[value]
} , default=identity)

To avoid the bquote, you could with with an exprssion list. Here's a helper function that will make that easier to work with.

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 you can draw your plot with

tree.lab <- expression(
  T1 = "Tree 1"[test], 
  T2 = "Tree 2", 
  T3 = "Tree 3",  
  T4 = "Tree 4", 
  T5 = "Tree 5"
)

ggplot(Orange, aes(x = age, y = circumference)) +
  facet_wrap(~tree2, labeller = label_expressions(tree.lab)) +
  geom_point()

Note that tree.lab is an expression object so all the values are not parsed and remain language objects.

Upvotes: 1

Related Questions