Jak dodać ogólną etykietę do aspektów w ggplot2?

84

Często mam wartości liczbowe do fasetowania. Chciałbym podać wystarczające informacje do zinterpretowania tych wartości fasetowania w dodatkowym tytule, podobnym do tytułów osi. Opcje etykietowania powtarzają dużo niepotrzebnego tekstu i nie nadają się do użytku w przypadku dłuższych zmiennych tytułów.

Jakieś sugestie?

Domyślny:

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)

wprowadź opis obrazu tutaj

Co bym chciał:

wprowadź opis obrazu tutaj

Najlepsze, co mogę zrobić w ggplot:

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

wprowadź opis obrazu tutaj

Jak wskazuje @Hendy, podobnie do: dodaj pomocniczą oś y do wykresów ggplot2 - spraw, aby był doskonały

Etienne Low-Décarie
źródło
1
Święta krowa. Byłem po prostu patrząc na to, uznał to za pośrednictwem google ... a teraz patrz pytano minutę temu. To pytanie wydaje się być pytanie samo w oparciu o jego komentarz, mimo tytułu, który może sugerować inaczej. Świetne makiety do zilustrowania. To jest dokładnie mój problem - byłoby miło, gdybym nie musiał wyjaśniać swoich liczbowych kategorii aspektów. Wykres powinien mówić sam za siebie z prostą etykietą wyjaśniającą, jakie były zmienne fasetowania.
Hendy,
3
Zapytałem Winstona Changa (nie znam jego uchwytu SO), jednego z głównych programistów ggplot, za pośrednictwem poczty elektronicznej. Uważa, że ​​nie jest to obecnie opcja, ale może rozważyć jej dodanie. Zasugerował, żebym dodał problem na githubie, więc tak zrobiłem
Hendy
1
Wygląda na to, że pojawiło się to na liście mailingowej i Winston dał mi znać. Stworzył oddział z ogólną implementacją tego dla topowych wytwórni. Zobacz wątek tutaj . @hadley: masz rację. Nie mam pojęcia, jak ciężko jest to w ogóle robić. Jeśli to się nigdy nie wydarzy ... moja wdzięczność za ggplot nadal przeważa :)
Hendy.
1
W pewnym momencie przestaję kłócić się z R / ggplot2 i wprowadzam pewne pożądane modyfikacje za pomocą edytora obrazów.
Andy
2
jakieś aktualizacje dotyczące najlepszych praktyk tutaj?
Arthur Yip

Odpowiedzi:

49

Ponieważ najnowsze ggplot2zastosowania gtablewewnętrzne są dość łatwe do zmodyfikowania liczby:

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)

wprowadź opis obrazu tutaj

Oczywiście możesz napisać funkcję, która automatycznie doda etykiety pasków. Przyszła wersja ggplot2może mieć taką funkcjonalność; nie jestem jednak pewien.

kohske
źródło
- Zastanawiam się, czy jest to nadal najczystsze podejście od wersji 0.9.3.1. Nie widzę czegoś, co wygląda jak „ta funkcjonalność” w najnowszej dokumentacji docs.ggplot2.org/0.9.3.1
yosukesabai
1
Wersja 0.9.3.1 zapewnia ggplotGrob()to samo co ggplot_gtable(ggplot_build()). Myślę, że to wciąż najlepszy sposób.
kohske
1
Jeśli się nie mylę, to rozwiązanie jest nieaktualne, ponieważ niektóre funkcje są teraz przestarzałe.
Remi. B
1
@ Remi.b wypróbuj teraz
rawr
3
To nie działa z ggplot2 3.2.1 i R 3.6.1. Brak komunikatu o błędzie, ale nie otrzymuję etykiet na wynikowym wykresie.
Calimo
5

Może jest na to lepszy sposób, ale możesz:

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
Diogo
źródło
1

Oprócz metody opisanej przez Kohske możesz dodać obramowanie do pól dodanych przez zmianę

col=NA

do

col=gray(0.5), linetype=1

Zmień też

fill=gray(0.5)

dla

fill=grey(0.8)

i

gp=gpar(col=gray(1))

do

gp=gpar(col=gray(0))

Jeśli chcesz, aby nowe słupki były zgodne z etykietami aspektów

to znaczy

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)))
Shannon Hodges
źródło