Reputation: 109864
When you want to add math symbols to facet_wrap
you used to be able to use the grid
packge as in (example taken from here):
library(ggplot2); library(grid)
d <- ggplot(diamonds, aes(carat, price, fill = ..density..))
xlim(0, 2) + stat_binhex(na.rm = TRUE) + opts(aspect.ratio = 1)
d <- d + facet_wrap(~ color, ncol = 4)
grob <- ggplotGrob(d)
strip_elem <- grid.ls(getGrob(grob, "strip.text.x", grep=TRUE, global=TRUE))$name
grob <- editGrob(grob, strip_elem[1], label=expression(Y[1]))
grid.draw(grob)
This no longer works as it gives this error:
> strip_elem <- grid.ls(getGrob(grob, "strip.text.x", grep=TRUE, global=TRUE))$name
Error in getGrob(grob, "strip.text.x", grep = TRUE, global = TRUE) :
It is only valid to get a child from a 'gTree'
> grob <- editGrob(grob, strip_elem[1], label=expression(Y[1]))
Error in editGrob(grob, strip_elem[1], label = expression(Y[1])) :
object 'strip_elem' not found
How can we add math symbols in version 0.9.2?
Upvotes: 4
Views: 1250
Reputation: 32789
Update It might be easier to use a facet_wrap_labeller function available from here.
library(ggplot2)
library(gtable)
d <- ggplot(diamonds, aes(carat, price, fill = ..density..)) +
xlim(0, 2) + stat_binhex(na.rm = TRUE) + theme(aspect.ratio = 1)
(d <- d + facet_wrap(~color, ncol = 4))
facet_wrap_labeller <- function(gg.plot, labels=NULL) {
require(gridExtra)
g <- ggplotGrob(gg.plot)
gg <- g$grobs
strips <- grep("strip_t", names(gg))
for(ii in seq_along(labels)) {
modgrob <- getGrob(gg[[strips[ii]]], "strip.text",
grep=TRUE, global=TRUE)
gg[[strips[ii]]]$children[[modgrob$name]] <- editGrob(modgrob,label=labels[ii])
}
g$grobs <- gg
class(g) = c("arrange", "ggplot",class(g))
return(g)
}
# Some arbitrary strip texts
StripTexts = expression(Y[1], E, F, G, H, I, J)
# Apply the facet_wrap_labeller function
g = facet_wrap_labeller(d, StripTexts)
# Draw it
g
Original solution with a minor edit to make selecting the strip text a little easier.
This works but it gets a bit messy in the middle. It uses ggplot2 0.9.2
and functions from the grid
and gtable
packages. There has to be a simpler way, and I'm hoping you can take something from this to work up a simpler solution.
The steps are:
expression(Y[1])
;Insert the modified strip element back into the original plot.
library(ggplot2); library(grid); library(gtable)
d <- ggplot(diamonds, aes(carat, price, fill = ..density..)) +
xlim(0, 2) + stat_binhex(na.rm = TRUE) + theme(aspect.ratio = 1)
(d <- d + facet_wrap(~color, ncol = 4))
# The aim is to change the strip text "D" to expression(Y[1])
# Winston's accessor function:
gt_getgrob <- function(gt, pattern) {
idx <- grep(pattern, gt$layout$name)
if (length(idx) > 1)
stop("More than one match for pattern '", pattern, "'")
gt$grobs[[idx]]
}
g = ggplotGrob(d)
g$layout # We want "strip_t-1"
strip <- gt_getgrob(g, "t-1") # Use the accessor function to extract it.
str(strip) # Locate the "D" label
strip$children[[2]]$label = expression(Y[1]) # Change the label.
grid.draw(strip) # Yes, it's worked
gt <- ggplot_gtable(ggplot_build(d))
gtable_show_layout(gt) # Get the layout of the original plot.
gt = gtable_add_grob(gt, strip, t=3, l=4, b=3, r=4) # Insert the modified strip element into the plot.
grid.newpage()
grid.draw(gt)
The result is:
Upvotes: 4