Use label_both() with expression - r

From ggplot2's reference manual, of label_both:
library(ggplot2)
mtcars$cyl2 <- factor(mtcars$cyl, labels = c("alpha", "beta", "gamma"))
p <- ggplot(mtcars, aes(wt, mpg)) + geom_point()
# Displaying both the values and the variables
p + facet_grid(. ~ cyl, labeller = label_both)
This will give us facet strips with both variable name and its values. However, say if I want to change the appearance of the variable name, but not change the values, e.g.:
expression(italic(cyl))
So that I can get a cyl: 4 instead of cyl: 4, is it possible to do it using the labeller function?

After a look at the docs and the source code label_both has no parse option. But similar to the approach in the answer referenced by #jared_mamrot in his comment you could use as_labeller to create a custom labeller for which you use label_parsed.
library(ggplot2)
mtcars$cyl2 <- factor(mtcars$cyl, labels = c("alpha", "beta", "gamma"))
p <- ggplot(mtcars, aes(wt, mpg)) +
geom_point()
p + facet_grid(. ~ cyl,
labeller = as_labeller(
~ paste0("italic(cyl):", .x), label_parsed
)
)

Related

R - when using facet_wrap, access the factor within the current facet

Consider the following (nonsensical, but working) plot:
ggplot(mtcars,
aes(x = as.factor(cyl), y = hp)) +
geom_boxplot() +
facet_wrap( ~ am) +
geom_text(label = "test")
I'd like to pass the value of am within each facet to the label argument of geom_text. So all the labels within the left facet would read "0", all the labels within the right facet would read "1".
How could I achieve this? Simply passing am doesn't work, and neither does .$am.
Sure, just provide the label inside mapping, like this:
... +
geom_text(aes(label = am))
You could pass it as a vector like this:
library(ggplot2)
ggplot(mtcars, aes(x = as.factor(cyl), y = hp)) +
geom_boxplot() +
facet_wrap( ~ am) +
geom_text(label = mtcars$am)
Created on 2022-11-03 with reprex v2.0.2

How to modify axis labels within ggplot labs()

Say I want to modify a ggplot axis label with the str_to_title() function.
library(tidyverse)
mtcars %>%
ggplot(aes(x = wt, y = mpg)) +
geom_point() +
labs(x = ~str_to_title(.x))
Rather than my x-axis being labeled 'Wt' it will be labeled 'str_to_title(.x)'. Is there a way to apply functions within the labs() function?
labs doesn't do programmatic NSE like many other components of ggplot2. One option is to define the columns programmatically, use aes_ and as.name (or other ways too) and it'll work.
library(ggplot2)
library(stringr) # str_to_title
xx <- "wt"; yy <- "mpg"
ggplot(mtcars, aes_(x = as.name(xx), y = as.name(yy))) +
geom_point() +
labs(x = str_to_title(xx))

R facet labels with expressions using label_parsed

I'm trying to put expressions into facet labels using label_parsed but with no success:
library(ggplot2)
mpg3 <- mpg
levels(mpg3$drv)[levels(mpg3$drv)=="4"] <- "4^{wd}"
levels(mpg3$drv)[levels(mpg3$drv)=="f"] <- "- Front %.% e^{pi * i}"
levels(mpg3$drv)[levels(mpg3$drv)=="r"] <- "4^{wd} - Front"
ggplot(mpg3, aes(x=displ, y=hwy)) + geom_point() +
facet_grid(. ~ drv, labeller = label_parsed)
The plot that I get lacks expressions - facet labels contain the original levels of drv variable.
If I type levels(mpg3$drv) I get character(0).
There are two problems - firstly mpg$drv is character, not factor, and secondly, you need to set the factor labels, not the levels. I think this is what you want...
mpg3 <- mpg
mpg3$drv <- factor(mpg3$drv,
levels=c("4","f","r"),
labels=c("4^{wd}","- Front %.% e^{pi * i}","4^{wd} - Front"))
ggplot(mpg3, aes(x=displ, y=hwy)) +
geom_point() +
facet_grid(. ~ drv, labeller = label_parsed)

automagically using labels (haven semantics) in ggplot2 plots

I'm plotting data marked up using haven semantics, i.e. variables and values have labels defined via attributes.
Often, these labels are also what I want in my axis titles and ticks.
library(ggplot2)
mtcars$mpg = haven::labelled(mtcars$mpg, labels = c("low" = 10, "high" = 30))
attributes(mtcars$mpg)$label = "miles per gallon"
ggplot(mtcars, aes(mpg, cyl)) + geom_point() +
scale_x_continuous(attributes(mtcars$mpg)$label,
breaks = attributes(mtcars$mpg)$labels,
labels = names(attributes(mtcars$mpg)$labels))
Could I write a helper that replaces that laborious scale_x_continuous statement with something that can more easily be iterated? E.g. something like
scale_x_continuous(label_from_attr, breaks = breaks_from_attr, labels = value_labels_from_attr). Or maybe even + add_labels_from_attributes() to replace the whole thing?
I'm aware that I can write/use helpers like Hmisc::label to slightly shorten the attribute-code above, but that's not what I want here.
I don't have a good scale, but you can use a function like this:
label_x <- function(p) {
b <- ggplot_build(p)
x <- b$plot$data[[b$plot$labels$x]]
p + scale_x_continuous(
attributes(x)$label,
breaks = attributes(x)$labels,
labels = names(attributes(x)$labels)
)
}
Then use as (+ won't do):
p <- ggplot(mtcars, aes(mpg, cyl)) + geom_point()
label_x(p)
Alternatively, use a pipe:
mtcars %>% { ggplot(., aes(mpg, cyl)) + geom_point() } %>% label_x()
Old solution
use_labelled <- function(l, axis = "x") {
if (axis == "x") {
scale_x_continuous(attributes(l)$label,
breaks = attributes(l)$labels,
labels = names(attributes(l)$labels))
}
if (axis == "y") {
scale_y_continuous(attributes(l)$label,
breaks = attributes(l)$labels,
labels = names(attributes(l)$labels))
}
}
Then you just give:
ggplot(mtcars, aes(mpg, cyl)) + geom_point() + use_labelled(mtcars$cyl)
Or for the y-axis:
ggplot(mtcars, aes(cyl, mpg)) + geom_point() + use_labelled(mtcars$cyl, "y")
Another approach is to write a wrapper for ggplot() that has its own class. Then attributes have full visibility when the corresponding print method is called. See ?ag.print from package 'yamlet' (0.2.1).
library(ggplot2)
library(yamlet)
library(magrittr)
mtcars$disp %<>% structure(label = 'displacement', unit = 'cu. in.')
mtcars$mpg %<>% structure(label = 'mileage', unit = 'miles/gallon')
mtcars$am %<>% factor(levels = c(0,1), labels = c('automatic','manual'))
mtcars$am %<>% structure(label = 'transmission')
agplot(mtcars, aes(disp, mpg, color = am)) + geom_point()

Label with mathematical expressions in two line with facet_grid for two grids in ggplot2

I want to add label with mathematical expressions in two line with facet_grid for two grids (See MWE). I can get that in one line, wonder to get in two lines (Beta in one line and Gamma in second line in second graph).
library(ggplot2)
p1 <- ggplot(mtcars, aes(x = mpg, y = wt)) + geom_point()
p1 + facet_grid(
facets = gear ~ vs + am
, labeller = label_both
)
p1 + facet_grid(
facets = gear ~ vs + am
, labeller =
label_bquote(
rows = alpha:.(gear)
, cols = list(beta:.(vs), gamma:.(am))
)
)
You can use atop() instead of list():
library(ggplot2)
ggplot(mtcars, aes(mpg, wt)) +
geom_point() +
facet_grid(gear ~ vs + am,
labeller = label_bquote(
rows = alpha:.(gear),
cols = atop(beta:.(vs), gamma:.(am))))
atop() is a brute force approach as it puts "x over y (no horizontal bar)"

Resources