How to Use Grid to Edit a Ggplot2 Object to Add Math Expressions to Facet Labels

How can I use grid to edit a ggplot2 object to add math expressions to facet labels?

This example should get you started:

library("ggplot2")
library("grid")

d <- ggplot(iris, aes(Sepal.Length, Sepal.Width)) +
geom_point() +
facet_wrap(~Species)
grob <- ggplotGrob(d)
strip_elem <- grid.ls(getGrob(grob, "strip.text.x", grep=TRUE, global=TRUE))$name

grob <- grid::editGrob(grob, strip_elem[1], label=expression(alpha[1]))
grob <- grid::editGrob(grob, strip_elem[2], label=expression(beta^2))
grob <- grid::editGrob(grob, strip_elem[3], label=expression(hat(gamma)))

grid.draw(grob)

modified grob

Update: this works with ggplot2 version 0.9.3 (although using grid is a fragile way to modify ggplot2 graphics)

grob[["grobs"]][["strip_t.1"]][["children"]][[2]][["label"]] <- expression(alpha[1])
grob[["grobs"]][["strip_t.2"]][["children"]][[2]][["label"]] <- expression(beta^2)
grob[["grobs"]][["strip_t.3"]][["children"]][[2]][["label"]] <- expression(hat(gamma))
grid.draw(grob)

Changing facet label to math formula in ggplot2

Perhaps somebody has changed the name of the edit-Grob function at some point. (Edit: It was removed by @hadley about 8 months ago.) There is no geditGrob but just editGrob from pkg:grid seems to work:

 d <- ggplot(diamonds, aes(carat, price, fill = ..density..)) +
xlim(0, 2) + stat_binhex(na.rm = TRUE) + opts(aspect.ratio = 1)

#Note: changes in ggplot2 functions cause this to fail from the very beginning now.
# Frank Harrell's answer this year suggests `facet_warp` now accepts `labeller`

d <- d + facet_wrap(~ color, ncol = 4)
grob <- ggplotGrob(d)
strip_elem <- grid.ls(getGrob(grob, "strip.text.x", grep=TRUE, global=TRUE))$name
#strip.text.x.text.1535
#strip.text.x.text.1541
#strip.text.x.text.1547
#strip.text.x.text.1553
#strip.text.x.text.1559
#strip.text.x.text.1565
#strip.text.x.text.1571
grob <- editGrob(grob, strip_elem[1], label=expression(Y[1]))
grid.draw(grob)

R : ggplot2 : facet_grid : how include math expressions in few (not all) labels?

Proposed Solution:

Prequisite:

activity <- as.numeric(c("44", "41", "48", "43", "42", "45", 
"44", "39", "47", "68", "88", "57"))
group <- c("first", "first", "first", "first", "first", "first",
"second", "second", "second", "second", "second", "second")
day <- c("0", "0", "0", "20", "20", "20", "0", "0", "0", "20",
"20", "20")
a <- data.frame(activity, group, day)
require(ggplot2)
levels(a$group) <- c("control", expression("100 µg " * .L^"-1" * ""))

Proposed Solution:

p1 <- qplot(day, activity, data = a)
p1 + facet_grid(. ~ group, labeller = label_parsed)

result:

Sample Image

Explanation

We create the labels structure as a string, where we create a formula, noting to use ~ to replace spaces... We then tell facet_grid() to parse the label string passed to it as a formula by setting labeller = label_parsed...

Note: The details of the display are described in ?plotmath, but note that geom_text() and facet_grid() use strings, not expressions.

I hope the above helps.

Reference:

See Hagley Wickham's page on labellers...: https://github.com/hadley/ggplot2/wiki/labeller

How to change facet labels?

Change the underlying factor level names with something like:

# Using the Iris data
> i <- iris
> levels(i$Species)
[1] "setosa" "versicolor" "virginica"
> levels(i$Species) <- c("S", "Ve", "Vi")
> ggplot(i, aes(Petal.Length)) + stat_bin() + facet_grid(Species ~ .)

Greek symbols in ggplot2 facet grid labels

p <- p + facet_grid(rows = vars(rho), cols = vars(rho0), 
labeller = label_bquote(rows = rho==.(rho),
cols = rho[0]==.(rho0)))

Sample Image

R facet labels with expressions using label_parsed

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)

Sample Image

How can I have a Greek symbol within one of my facet labels?

Here is a trick that uses labeller=label_parsed.

First, define labels for df$genes that uses the expression to be parsed:

df$genes <- factor(df$genes, levels = c("BA","MLL","pos","neg","PMLalpha+"),
ordered = TRUE, labels=c("BA","MLL","pos","neg",expression(paste("PML", alpha,"+"))))

Then use labeller=label_parsed in facet_wrap:

ggplot(df,aes(x=genes, y=value)) + geom_boxplot() + 
facet_wrap(~genes, ncol = 5, scales = "free_x", labeller = label_parsed)

As you can see this messes with the x-axis labels, but you can fix it in scale_x_discrete as follows:

ggplot(df,aes(x=genes, y=value)) + geom_boxplot() + 
facet_wrap(~genes, ncol = 5, scales = "free_x", labeller = label_parsed) +
scale_x_discrete(name="",
breaks = c("BA","MLL","pos","neg","paste(\"PML\", alpha, \"+\")"),
labels = c("BA","MLL","pos","neg", expression(paste("PML", alpha,"+"))))

Sample Image

Edit: In response to follow-up question posted, here is the solution for using label_parsed for more than one variable. Includes requested space in the variable strings.

df$var2 <- c(rep(c('trt a','trt b'), NROW(df)/2),'trt a')
df$var2 <- factor(df$var2, levels=c('trt a','trt b'), ordered=T, labels=c(expression(paste("trt ", alpha)), expression(paste("trt ", beta))))

ggplot(df,aes(x=var2, y=value)) + geom_boxplot() +
facet_wrap(~var2, ncol = 5, scales = "free_x", labeller = label_parsed)

Fix the x-axis:

ggplot(df,aes(x=var2, y=value)) + geom_boxplot() + 
facet_wrap(~var2, ncol = 5, scales = "free_x", labeller = label_parsed) +
scale_x_discrete(name="",
breaks = c(expression(paste("trt ", alpha)), expression(paste("trt ", beta))),
labels = c(expression(paste("trt ", alpha)), expression(paste("trt ", beta))))

Sample Image

Add data frame variable to ggplot2 facet label

It is possible to pass the column en to your labelling function by changing .data to ., and using {} to let the pipe know that there are two data args.

mtcars %>%
group_by(cyl) %>%
mutate(en = 5) %>%
{ggplot(., aes(drat, wt)) +
facet_wrap(~ cyl, labeller = app_n(.n = .$en))}

This returns the expected labels.

However, using a data frame variable itself to label your facets implies that there are as many facets as rows. Otherwise only the first few labels are used and a warning is returned.

Switching position of two facet strip labels and combine one label across columns

This could be easily done with ggh4x package written by teunbrand:
Using facet_nested_wrap function:
You can change which one you want to combine, just change the order in facet_nested_wrap:

library(tidyverse)
#install.packages("ggh4x")
library(ggh4x)

dt %>%
ggplot(aes(x=generation, y= days))+
geom_bar(stat = "identity")+
facet_nested_wrap(~year + device_type, nrow = 1, ncol=4)

Sample Image



Related Topics



Leave a reply



Submit