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
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
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))
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)
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()
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)"