I'm trying to find a convenient solution to a scenario where I have multi-line, plain-text labels for one faceting dimension and plotmath-style math expressions for the other faceting dimensions. The various solutions to multi-line strip labels (such as here) are a bit clunky for my case; I have factor labels in snake_case
and want to be able to convert them all to multiline versions programmatically without descending into substitute(bquote(parse(...))
hell (although solutions along those lines would also be accepted).
The direction I went was to (try to) write a custom labeller that would apply label_parsed()
or leave the labels alone depending on whether they contained newlines or not. I can't seem to get quite the right syntax for the parsed stuff. The current structure of the multi-line, unparsed stuff is
List of 1
$ : chr [1:4] "peak\ntime" "peak\nvirulence" "equilibrium\nvirulence" "relative\npeak"
which works, but the parsed stuff is
List of 3
$ :List of 1
..$ : expression(beta)
$ :List of 1
..$ : expression(gamma)
$ :List of 1
..$ : expression(x[1])
which doesn't. Applying unlist(r)
and unlist(r,recursive=FALSE)
to this structure both give error messages ...
The result (shown below) is that all three of the parsed labels get stacked up in the first column ...
?label_parsed
says
The return value must be a rectangular list where each 'row' characterises a single facet. The list elements can be either character vectors or lists of plotmath expressions. When multiple elements are returned, they get displayed on their own new lines (i.e., each facet gets a multi-line strip of labels).
Setup: load package, define old and new labels
library(ggplot2); theme_set(theme_bw())
orig_sum_labs <- c("peak_time","peak_vir","eq_vir","rel_peak")
new_sum_labs <- c("peak time","peak virulence","equilibrium virulence",
"relative peak")
fake <- data.frame(f1=rep(orig_sum_labs,each=12),
f2=factor(rep(1:3,16),levels=1:3,
labels=c("beta","gamma","x[1]")),
x=rep(1:4,12),y=rep(1:4,12))
Put newlines into labels:
nn <- gsub(" ","\n",new_sum_labs)
fake$f1 <- factor(fake$f1,levels=orig_sum_labs,labels=nn)
My labeller function:
L <- function(labels,multi_line=TRUE) {
r <- if (all(grepl("\n",labels[[1]]))) {
list(as.character(labels[[1]]))
} else {
label_parsed(labels[[1]],multi_line=multi_line)
}
## browser()
return(r)
}
class(L) <- "labeller"
Try it out:
ggplot(fake,aes(x,y))+geom_point()+
facet_grid(f1~f2,labeller=L)
To remove the label from facet plot, we need to use “strip. text. x” argument inside the theme() layer with argument 'element_blank()'.
Faceting is the process that split the chart window in several small parts (a grid), and display a similar chart in each section. Each section usually shows the same graph for a specific group of the dataset. The result is usually called small multiple.
Oops. It's a bit magical (and I would happily accept answers that explain clearly what's going on), but I managed to solve my problem. In my labeller function above,
label_parsed(labels[[1]],multi_line=multi_line)
doesn't work, but
label_parsed(labels,multi_line=multi_line)
works ...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With