Изменение метки фасета на математическую формулу в ggplot2
Интересно как поменять facet
метка для математической формулы в ggplot2
,
d <- ggplot(diamonds, aes(carat, price, fill = ..density..)) +
xlim(0, 2) + stat_binhex(na.rm = TRUE) + opts(aspect.ratio = 1)
d + facet_wrap(~ color, ncol = 4)
Например, я хочу изменить метку фасета с D
в Y[1]
где 1 - индекс. Заранее спасибо за помощь.
Я нашел этот ответ, но он не работает для меня. я использую R 2.15.1
а также ggplot2 0.9.1
,
5 ответов
Возможно, кто-то изменил имя функции edit-Grob в какой-то момент. (Редактировать: он был удален @hadley около 8 месяцев назад.) geditGrob
но просто editGrob
из pkg:grid вроде работает:
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)
Вы можете редактировать гробов в gtable,
ggplot(diamonds, aes(carat, price, fill = ..density..)) +
xlim(0, 2) + stat_binhex(na.rm = TRUE) + facet_wrap(~ color, ncol = 4)
for(ii in 1:7)
grid.gedit(gPath(paste0("strip_t-", ii), "strip.text"),
grep=TRUE, label=bquote(gamma[.(ii)]))
в качестве альтернативы, если вы хотите сохранить гроб,
g <- ggplotGrob(d)
gg <- g$grobs
strips <- grep("strip_t", names(gg))
for(ii in strips)
gg[[ii]] <- editGrob(getGrob(gg[[ii]], "strip.text",
grep=TRUE, global=TRUE),
label=bquote(gamma[.(ii)]))
g$grobs <- gg
использование ggsave потребовало бы дополнительной (безобразной) работы, так как нужно обмануть тест для класса ggplot... Я считаю, что будет проще вызвать pdf() ; grid.draw(g); dev.off()
в явном виде.
Редактировать Роландом:
Я сделал небольшое исправление и обернул его в функцию:
facet_wrap_labeller <- function(gg.plot,labels=NULL) {
#works with R 3.0.1 and ggplot2 0.9.3.1
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))
g
}
Это позволяет печатать красиво и даже ggsave
может быть использован.
По состоянию на ggplot2
2.1.0 labeller
был реализован для facet_wrap
,
Только что натолкнулся на эту очень полезную функцию от roland и baptiste, но нуждался в немного другом случае использования, где оригинальные заголовки переноса должны быть преобразованы функцией, а не предоставлены как фиксированное значение. Я публикую немного измененную версию оригинальной функции на случай, если она пригодится кому-либо еще. Это позволяет использовать как именованные (фиксированные значения) выражения для полосок переноса, так и использовать пользовательские функции и функции, уже предоставленные ggplot2 для facet_grid
labeller
параметр (такой как label_parsed
а также label_bquote
).
facet_wrap_labeller <- function(gg.plot, labels = NULL, labeller = label_value) {
#works with R 3.1.2 and ggplot2 1.0.1
require(gridExtra)
# old labels
g <- ggplotGrob(gg.plot)
gg <- g$grobs
strips <- grep("strip_t", names(gg))
modgrobs <- lapply(strips, function(i) {
getGrob(gg[[i]], "strip.text", grep=TRUE, global=TRUE)
})
old_labels <- sapply(modgrobs, function(i) i$label)
# find new labels
if (is.null(labels)) # no labels given, use labeller function
new_labels <- labeller(names(gg.plot$facet$facets), old_labels)
else if (is.null(names(labels))) # unnamed list of labels, take them in order
new_labels <- as.list(labels)
else { # named list of labels, go by name where provided, otherwise keep old
new_labels <- sapply(as.list(old_labels), function(i) {
if (!is.null(labels[[i]])) labels[[i]] else i
})
}
# replace labels
for(i in 1:length(strips)) {
gg[[strips[i]]]$children[[modgrobs[[i]]$name]] <-
editGrob(modgrobs[[i]], label=new_labels[[i]])
}
g$grobs <- gg
class(g) = c("arrange", "ggplot",class(g))
return(g)
}
Обновление / предупреждение
Для более новых версий gridExtra
пакет вы получите ошибку Error: No layers in plot
при запуске этой функции, потому что arrange
больше не в gridExtra
и R пытается интерпретировать это как ggplot
, Вы можете исправить это путем (повторного) введения print
функция для arrange
учебный класс:
print.arrange <- function(x){
grid::grid.draw(x)
}
Теперь это должно позволить визуализировать график, и вы можете использовать ggsave()
например, вот так: ggsave("test.pdf", plot = facet_wrap_labeller(p, labeller = label_parsed))
Примеры
Несколько примеров использования:
# artificial data frame
data <- data.frame(x=runif(16), y=runif(16), panel = rep(c("alpha", "beta", "gamma","delta"), 4))
p <- ggplot(data, aes(x,y)) + geom_point() + facet_wrap(~panel)
# no changes, wrap panel headers stay the same
facet_wrap_labeller(p)
# replace each panel title statically
facet_wrap_labeller(p, labels = expression(alpha^1, beta^1, gamma^1, delta^1))
# only alpha and delta are replaced
facet_wrap_labeller(p, labels = expression(alpha = alpha^2, delta = delta^2))
# parse original labels
facet_wrap_labeller(p, labeller = label_parsed)
# use original labels but modifying them via bquote
facet_wrap_labeller(p, labeller = label_bquote(.(x)^3))
# custom function (e.g. for latex to expression conversion)
library(latex2exp)
facet_wrap_labeller(p, labeller = function(var, val) {
lapply(paste0("$\\sum\\", val, "$"), latex2exp)
})
Спасибо за другие ответы и комментарии за упоминание. По-прежнему было не совсем понятно, как использовать синтаксический анализатор меток, поэтому я добавляю сюда простой воспроизводимый пример.
library(dplyr)
library(ggplot2)
iris %>%
mutate(Species = factor(Species,
levels = c("setosa", "versicolor", "virginica"),
labels = c("m^2",
expression(bar(x) == sum(frac(x[i], n), i==1, n)),
expression("Q[t-1]")))) %>%
ggplot(aes(x = Petal.Length, y = Petal.Width)) +
geom_point() +
facet_wrap(~Species, labeller = label_parsed)
Синтаксис отличается от латексной формулы, потому что
label_parsed
интерпретирует метку как математическое выражение. Например индексы пишутся
x_i
в латексе и
x[i]
в математических выражениях сюжета. Вы можете найти примеры математических формул на странице справки
plotmath
функция.