Как добавить общую метку к фасетам в ggplot2?

84

У меня часто есть числовые значения для огранки. Я хочу предоставить достаточно информации для интерпретации этих значений фасетов в дополнительном заголовке, аналогичном заголовкам осей. Параметры этикетировщика повторяют много ненужного текста и не могут использоваться для более длинных заголовков переменных.

Какие-либо предложения?

По умолчанию:

test<-data.frame(x=1:20, y=21:40, facet.a=rep(c(1,2),10), facet.b=rep(c(1,2), each=20))
qplot(data=test, x=x, y=y, facets=facet.b~facet.a)

введите описание изображения здесь

Что бы мне понравилось:

введите описание изображения здесь

Лучшее, что я могу сделать в ggplot:

qplot(data=test, x=x, y=y)+facet_grid(facet.b~facet.a, labeller=label_both)

введите описание изображения здесь

Как указано @Hendy, аналогично: добавить вторичную ось y к графикам ggplot2 - сделать его идеальным

Этьен Лоу-Декари
источник
1
Святая корова. Я просто искал это, нашел это через Google ... и теперь вижу, что минуту назад его спросили. Этот вопрос, кажется, задает то же самое, основываясь на его комментарии, несмотря на заголовок, который может подразумевать иное. Отличные мокапы для иллюстрации. Это как раз моя проблема - было бы неплохо, если бы мне не приходилось объяснять свои числовые аспекты категорий. График должен говорить сам за себя с простой меткой, объясняющей, какие были переменные фасетирования.
Hendy
3
Я спросил Уинстона Чанга (не знаю, как он работает), одного из основных разработчиков ggplot, по электронной почте. Он не думает, что в настоящее время это вариант, но может подумать о его добавлении. Он предложил мне добавить проблему на github, что я и сделал
Hendy
1
Похоже, это появилось в списке рассылки, и Уинстон сообщил мне. Он создал ветку с общей реализацией этого для топ-лейблов. Смотрите ветку здесь . @hadley: вы правы. Понятия не имею, насколько это сложно в целом. Если этого никогда не произойдет ... моя благодарность за ggplot все еще преобладает :)
Hendy
1
В какой-то момент я перестаю пытаться спорить с R / ggplot2 и вносить желаемые изменения с помощью редактора изображений.
Энди
2
какие-нибудь новости о передовой практике здесь?
Артур Йип

Ответы:

49

Поскольку последние ggplot2используются для gtableвнутреннего использования , довольно легко изменить фигуру:

library(ggplot2)
test <- data.frame(x=1:20, y=21:40, 
                   facet.a=rep(c(1,2),10), 
                   facet.b=rep(c(1,2), each=20))
p <- qplot(data=test, x=x, y=y, facets=facet.b~facet.a)

# get gtable object
z <- ggplotGrob(p)

library(grid)
library(gtable)
# add label for right strip
z <- gtable_add_cols(z, unit(z$widths[[7]], 'cm'), 7)
z <- gtable_add_grob(z, 
                     list(rectGrob(gp = gpar(col = NA, fill = gray(0.5))),
                          textGrob("Variable 1", rot = -90, gp = gpar(col = gray(1)))),
                     4, 8, 6, name = paste(runif(2)))

# add label for top strip
z <- gtable_add_rows(z, unit(z$heights[[3]], 'cm'), 2)
z <- gtable_add_grob(z, 
                     list(rectGrob(gp = gpar(col = NA, fill = gray(0.5))),
                          textGrob("Variable 2", gp = gpar(col = gray(1)))),
                     3, 4, 3, 6, name = paste(runif(2)))

# add margins
z <- gtable_add_cols(z, unit(1/8, "line"), 7)
z <- gtable_add_rows(z, unit(1/8, "line"), 3)

# draw it
grid.newpage()
grid.draw(z)

введите описание изображения здесь

Конечно, вы можете написать функцию, которая автоматически добавит метки полос. В будущей версии ggplot2может быть эта функция; хотя не уверен.

Коске
источник
- Мне интересно, по-прежнему ли это самый чистый подход с версии 0.9.3.1. Я не вижу чего-то похожего на «эту функциональность» в последней документации docs.ggplot2.org/0.9.3.1
yosukesabai
1
Версия 0.9.3.1 предоставляет ggplotGrob()то же самое, что и ggplot_gtable(ggplot_build()). Я считаю, что это лучший способ.
kohske
1
Если я не ошибаюсь, это решение больше не действует, так как некоторые функции устарели.
Remi.b 01
1
@ Remi.b попробуйте прямо сейчас
rawr
3
Это не работает с ggplot2 3.2.1 и R 3.6.1. Нет сообщения об ошибке, но я не получаю ярлыков на полученном графике.
Калимо
5

Возможно, есть лучший способ сделать это, но вы можете:

fac1 = factor(rep(c('a','b'),10))
fac2 = factor(rep(c('a','b'),10))
data = data.frame(x=1:10, y=1:10, fac1=fac1, fac2=fac2)
p = ggplot(data,aes(x,y)) + ggplot2::geom_point() + 
facet_grid(fac1~fac2)
p + theme(plot.margin = unit(c(1.5,1.5,0.2,0.2), "cm"))
grid::grid.text(unit(0.98,"npc"),0.5,label = 'label ar right', rot = 270) # right
grid::grid.text(unit(0.5,"npc"),unit(.98,'npc'),label = 'label at top', rot = 0)   # top
Диого
источник
1

В дополнение к методу, описанному Коске, вы можете добавить границу к добавленным полям, изменив

col=NA

к

col=gray(0.5), linetype=1

Также измените

fill=gray(0.5)

за

fill=grey(0.8)

и

gp=gpar(col=gray(1))

к

gp=gpar(col=gray(0))

Если вы хотите, чтобы новые полосы совпадали с метками фасетов

т.е.

z <- gtable_add_grob(z, 
      list(rectGrob(gp = gpar(col = gray(0.5), linetype=1, fill = gray(0.8))),
      textGrob("Variable 1", rot = -90, gp = gpar(col = gray(0)))),
      4, 8, 6, name = paste(runif(2)))
Шеннон Ходжес
источник