2016-12-24 18 views
5

Narysowałem panele 2d pogrupowane według dwóch czynników za pomocą facet_wrap.jak zmniejszyć pionowe odstępy między etykietami aspektów przy użyciu facet_wrap?

minimalny przykład:

library(ggplot2) 
ggplot(mpg, aes(displ, hwy)) + 
    geom_point() + 
    facet_wrap(~ cyl + drv) 

Etykieta na górnej części każdego panelu posiada dwa rzędy, chce zmniejszyć odległość pomiędzy dwoma rzędami napisu. Jak shoud robię to poprawnie?

Próbowałem:

ggplot(mpg, aes(displ, hwy)) + 
    geom_point() + 
    facet_wrap(~ cyl + drv) + 
    theme(
     strip.text = element_text(
      margin = margin(t = 0, r = 0, b = 0, l = 0, unit = "pt") 
     ) 
    ) 

ale to nie działa.

Z góry dziękuję.

Odpowiedz

4

Można określić drukarki etykiet, która stawia etykiety do tej samej listwy zamiast tworzyć dwa paski:

ggplot(mpg, aes(displ, hwy)) + 
    geom_point() + 
    facet_wrap(~ cyl + drv, 
      labeller = function (labels) { 
       labels <- lapply(labels, as.character) 
       list(do.call(paste, c(labels, list(sep = "\n")))) 
      }) 

resulting plot

4

Zaakceptowanych odpowiedź jest najprostsza i najprostszy sposób, aby osiągnąć pożądany wynik , ale użyłem tego pytania jako okazji, aby dowiedzieć się więcej o pracy z grobami i pomyślałem, że podzielę się tym, czego się dowiedziałem.

Aby zmodyfikować odstępy między etykietami aspektu, możemy manipulować leżącymi poniżej grobami. Aby to zrobić, najpierw wygeneruj grob działki:

library(ggplot2) 
library(grid) 
p <- ggplot(mpg, aes(displ, hwy)) + 
    geom_point() + 
    facet_wrap(~ cyl + drv) 
g <- ggplotGrob(p) 

Teraz możemy sprawdzić groby. Paski międzykręgowe są grobs 47 do 55 (9 grobs) i widzimy, że każdy grob pasek jest faktycznie tabelę grobs:

g 
# TableGrob (21 x 15) "layout": 62 grobs 
#  z   cells  name         grob 
# 1 0 (1-21, 1-15) background  rect[plot.background..rect.614] 
# 2 1 (7- 7, 4- 4) panel-1-1    gTree[panel-1.gTree.33] 
# 3 1 (12-12, 4- 4) panel-2-1    gTree[panel-4.gTree.78] 
# ... 
# 47 2 (16-16, 4- 4) strip-t-1-3       gtable[strip] 
# 48 2 (16-16, 8- 8) strip-t-2-3       gtable[strip] 
# 49 2 (16-16,12-12) strip-t-3-3       gtable[strip] 
# 50 2 (11-11, 4- 4) strip-t-1-2       gtable[strip] 
# 51 2 (11-11, 8- 8) strip-t-2-2       gtable[strip] 
# 52 2 (11-11,12-12) strip-t-3-2       gtable[strip] 
# 53 2 (6- 6, 4- 4) strip-t-1-1       gtable[strip] 
# 54 2 (6- 6, 8- 8) strip-t-2-1       gtable[strip] 
# 55 2 (6- 6,12-12) strip-t-3-1       gtable[strip] 
# 56 4 (4- 4, 4-12)  xlab-t       zeroGrob[NULL] 
# ... 

Skupiając się na grob 47, możemy drążyć w strukturę ...

str(g$grobs[[47]], m = 1) 
str(g$grobs[[47]]$grobs, m = 1) 
str(g$grobs[[47]]$grobs[[1]], m = 1) 
str(g$grobs[[47]]$grobs[[1]]$children, m = 1) 
str(g$grobs[[47]]$grobs[[1]]$children[[2]], m = 1) 
str(g$grobs[[47]]$grobs[[1]]$children[[2]]$children, m = 1) 

... dopóki nie dowiemy się, jak etykiety międzykręgowe są określone: ​​

str(g$grobs[[47]]$grobs[[1]]$children[[2]]$children[[1]], m = 1) 
# List of 11 
# $ label  : chr "8" 
# $ x   :Class 'unit' atomic [1:1] 0.5 
# .. ..- attr(*, "valid.unit")= int 0 
# .. ..- attr(*, "unit")= chr "npc" 
# $ y   :Class 'unit' atomic [1:1] 0.5 
# .. ..- attr(*, "valid.unit")= int 0 
# .. ..- attr(*, "unit")= chr "npc" 
# $ just   : chr "centre" 
# $ hjust  : NULL 
# $ vjust  : NULL 
# $ rot   : num 0 
# $ check.overlap: logi FALSE 
# $ name   : chr "GRID.text.322" 
# $ gp   :List of 6 
# ..- attr(*, "class")= chr "gpar" 
# $ vp   : NULL 
# - attr(*, "class")= chr [1:3] "text" "grob" "gDesc" 

teraz możemy po prostu zmienić wartość dla y tak, że etykieta na najwyższym Grob jest nea r dół, a etykieta dolnego groba znajduje się w górnej części. Robię to tylko dla pasków facet w skrajnej lewej kolumnie, dzięki czemu możemy zobaczyć różnicę:

for (i in c(47, 50, 53)) { 
    g$grobs[[i]]$grobs[[1]]$children[[2]]$children[[1]]$y = unit(0.1, "npc") 
    g$grobs[[i]]$grobs[[2]]$children[[2]]$children[[1]]$y = unit(0.9, "npc") 
} 
grid.newpage() 
grid.draw(g) 

wyjściowa: enter image description here

Powiązane problemy