Czy istnieje sposób na zmianę odstępów między elementami legendy w ggplot2?


120

Czy istnieje sposób na zmianę odstępów między elementami legendy w ggplot2? Obecnie mam

legend.position ="top" 

która automatycznie tworzy poziomą legendę. Jednak odstępy między elementami są bardzo małe i zastanawiam się, jak rozmieścić je dalej od siebie.


Przydałoby się mieć aktualne rozwiązanie tego problemu teraz, które optsjest amortyzowane.
— geoteoria


3
Odpowiedź Tunga, obecnie na dole tego wątku, ma aktualizację z lipca 2018 r. Błędy zostały naprawione, a hackerskie obejścia, takie jak to w powyższym pastebin, nie są już potrzebne.
— PatrickT,

Odpowiedzi:


90

ggplot2 v3.0.0wydany w lipcu 2018 posiada opcje pracy zmodyfikować legend.spacing.x, legend.spacing.yi legend.text.

Przykład: Zwiększ poziome odstępy między klawiszami legendy

library(ggplot2)

ggplot(mtcars, aes(factor(cyl), fill = factor(cyl))) + 
  geom_bar() +
  coord_flip() +
  scale_fill_brewer("Cyl", palette = "Dark2") +
  theme_minimal(base_size = 14) +
  theme(legend.position = 'top', 
        legend.spacing.x = unit(1.0, 'cm'))

Uwaga: jeśli chcesz tylko rozszerzyć odstępy z prawej strony tekstu legendy, użyj stringr::str_pad()

Przykład: Przenieś etykiety klucza legendy na dół i zwiększ odstępy w pionie

ggplot(mtcars, aes(factor(cyl), fill = factor(cyl))) + 
  geom_bar() +
  coord_flip() +
  scale_fill_brewer("Cyl", palette = "Dark2") +
  theme_minimal(base_size = 14) +
  theme(legend.position = 'top', 
        legend.spacing.x = unit(1.0, 'cm'),
        legend.text = element_text(margin = margin(t = 10))) +
  guides(fill = guide_legend(title = "Cyl",
                             label.position = "bottom",
                             title.position = "left", title.vjust = 1)) 

Przykład: dla scale_fill_xxx&guide_colorbar

ggplot(mtcars, aes(mpg, wt)) +
  geom_point(aes(fill = hp), pch = I(21), size = 5)+
  scale_fill_viridis_c(guide = FALSE) +
  theme_classic(base_size = 14) +
  theme(legend.position = 'top', 
        legend.spacing.x = unit(0.5, 'cm'),
        legend.text = element_text(margin = margin(t = 10))) +
  guides(fill = guide_colorbar(title = "HP",
                               label.position = "bottom",
                               title.position = "left", title.vjust = 1,
                               # draw border around the legend
                               frame.colour = "black",
                               barwidth = 15,
                               barheight = 1.5)) 


W przypadku legend pionowych ustawienie legend.key.sizezwiększa tylko rozmiar kluczy legendy, a nie odstępy między nimi w pionie

ggplot(mtcars) +
  aes(x = cyl, fill = factor(cyl)) +
  geom_bar() +
  scale_fill_brewer("Cyl", palette = "Dark2") +
  theme_minimal(base_size = 14) +
  theme(legend.key.size = unit(1, "cm"))

Aby zwiększyć odległość między klawiszami legendy, legend-draw.rkonieczna jest modyfikacja funkcji. Zobacz ten numer, aby uzyskać więcej informacji

# function to increase vertical spacing between legend keys
# @clauswilke
draw_key_polygon3 <- function(data, params, size) {
  lwd <- min(data$size, min(size) / 4)

  grid::rectGrob(
    width = grid::unit(0.6, "npc"),
    height = grid::unit(0.6, "npc"),
    gp = grid::gpar(
      col = data$colour,
      fill = alpha(data$fill, data$alpha),
      lty = data$linetype,
      lwd = lwd * .pt,
      linejoin = "mitre"
    ))
}

# register new key drawing function, 
# the effect is global & persistent throughout the R session
GeomBar$draw_key = draw_key_polygon3

ggplot(mtcars) +
  aes(x = cyl, fill = factor(cyl)) +
  geom_bar() +
  scale_fill_brewer("Cyl", palette = "Dark2") +
  theme_minimal(base_size = 14) +
  theme(legend.key = element_rect(color = NA, fill = NA),
        legend.key.size = unit(1.5, "cm")) +
  theme(legend.title.align = 0.5)


3
Dziękuję za zwrócenie uwagi. To jest taka wspaniała nowa funkcja, zawsze używałem dirty-fix @ user2568648, haha!
— Tjebo

1
Twoja funkcja zwiększania odstępów w pionie między klawiszami legendy jest jedynym rozwiązaniem, które znalazłem, które działa dokładnie tak, jak chcę i jest łatwe w użyciu. Dzięki!
— Docconcoct

69

Myślę, że najlepszą opcją jest użycie guide_legendw guides:

p + guides(fill=guide_legend(
                 keywidth=0.1,
                 keyheight=0.1,
                 default.unit="inch")
      )

Zwróć uwagę na użycie default.unit, nie ma potrzeby ładowania gridpakietu.


2
To wymaga więcej głosów pozytywnych, inne odpowiedzi są nieaktualne.
— Brandon Bertelsen

8
Może to działać w przypadku legend poziomych. Jednak w mojej legendzie pionowej po prawej stronie wykresu zwiększa to tylko wysokość klucza, a nie odstępy między klawiszami. Moje klucze legendy są nadal bardzo blisko siebie.
— Muhsin Zahid Ugur

9
Jak mówi Mushin, to mija się z celem, podobnie jak w przypadku innych odpowiedzi, jeśli legenda jest PIONOWA , rozciąga klawisze legendy (np. Segmenty linii) bez wypełniania przestrzeni między klawiszami.
— PatrickT

Dobrze współpracuje z geom_line i geom_point.
— Niels Holst

45

Prosta poprawka, której używam, aby dodać spację w legendach poziomych, po prostu dodaj spacje w etykietach (patrz wyciąg poniżej):

  scale_fill_manual(values=c("red","blue","white"),
                    labels=c("Label of category 1          ",
                             "Label of category 2          ",
                             "Label of category 3"))

13
To jedyna jak dotąd odpowiedź, która dotyczy tego pytania! Może to być pomocne w przypadku wielu wpisów: scale_fill_manual(values=values, labels=setNames(paste(labels, " "), entries)).
— SaschaH

2
Technicznie niezbyt ładne, zwłaszcza gdy trzeba wprowadzić te przestrzenie do poziomów współczynników, ale jest to jedyne działające rozwiązanie.
— Patrick Bucher

2
Lub możemy użyć str_pad, aby trochę ułatwić życie
— Tung,

37

Teraz to optsjest przestarzałe w ggplot2pakiecie, themezamiast tego należy użyć funkcji :

library(grid) # for unit()
... + theme(legend.key.height=unit(3,"line"))
... + theme(legend.key.width=unit(3,"line"))

18
To rozwiązanie zmienia wysokość / szerokość pudełek w przeciwieństwie do odstępów między nimi.
— Berk U.

25

Aby dodać odstępy między wpisami w legendzie, dostosuj marginesy elementu motywu legend.text .

Aby dodać 30 punktów miejsca po prawej stronie każdej etykiety legendy (może być przydatne w przypadku legendy poziomej):

p + theme(legend.text = element_text(
    margin = margin(r = 30, unit = "pt")))

Aby dodać 30 punktów miejsca po lewej stronie każdej etykiety legendy (może być przydatne w przypadku legendy pionowej):

p + theme(legend.text = element_text(
    margin = margin(l = 30, unit = "pt")))

za ggplot2obiekt p. Słowa kluczowe to legend.texti margin.

[Uwaga dotycząca edycji: kiedy ta odpowiedź została opublikowana po raz pierwszy, wystąpił błąd. Błąd został już naprawiony]


3
Błąd został już naprawiony, to powinna być zaakceptowana odpowiedź.
— giocomai

1
Zobacz także odpowiedź Tunga na aktualizację z lipca 2018 w tych sprawach.
— PatrickT

17

Wygląda na to, że najlepszym podejściem (w 2018 roku) jest użycie legend.key.sizepod themeobiektem. (np. patrz tutaj ).

#Set-up:
    library(ggplot2)
    library(gridExtra)

    gp <- ggplot(data = mtcars, aes(mpg, cyl, colour = factor(cyl))) +
        geom_point()

Jest to naprawdę łatwe, jeśli używasz theme_bw():

  gpbw <- gp + theme_bw()

#Change spacing size:

  g1bw <- gpbw + theme(legend.key.size = unit(0, 'lines'))
  g2bw <- gpbw + theme(legend.key.size = unit(1.5, 'lines'))
  g3bw <- gpbw + theme(legend.key.size = unit(3, 'lines'))

  grid.arrange(g1bw,g2bw,g3bw,nrow=3)

wprowadź opis obrazu tutaj

Jednak w przeciwnym razie nie działa to tak dobrze (np. Jeśli potrzebujesz szarego tła na swoim symbolu legendy):

  g1 <- gp + theme(legend.key.size = unit(0, 'lines'))
  g2 <- gp + theme(legend.key.size = unit(1.5, 'lines'))
  g3 <- gp + theme(legend.key.size = unit(3, 'lines'))

  grid.arrange(g1,g2,g3,nrow=3)

#Notice that the legend symbol squares get bigger (that's what legend.key.size does). 

#Let's [indirectly] "control" that, too:
  gp2 <- g3
  g4 <- gp2 + theme(legend.key = element_rect(size = 1))
  g5 <- gp2 + theme(legend.key = element_rect(size = 3))
  g6 <- gp2 + theme(legend.key = element_rect(size = 10))

  grid.arrange(g4,g5,g6,nrow=3)   #see picture below, left

Zwróć uwagę, że białe kwadraty zaczynają blokować tytuł legendy (i ostatecznie sam wykres, jeśli zwiększaliśmy wartość).

  #This shows you why:
    gt <- gp2 + theme(legend.key = element_rect(size = 10,color = 'yellow' ))

wprowadź opis obrazu tutaj

Nie do końca znalazłem obejście tego problemu ... Daj mi znać w komentarzach, jeśli masz pomysł, a zaktualizuję odpowiednio!

  • Zastanawiam się, czy istnieje sposób na ponowne nałożenie warstw za pomocą $layers...

Uczyń legend.keyprzejrzystym:theme(legend.key = element_rect(size = 30,color=alpha("transparent",0)))
— ukosteopath

1
to była najprostsza odpowiedź i najłatwiejsza w użyciu imo
— Blacklivesmatter

14

Z pracy Koshke na ggplot2 i jego blogu (blog Koshke )

... + theme(legend.key.height=unit(3,"line")) # Change 3 to X
... + theme(legend.key.width=unit(3,"line")) # Change 3 to X

Wpisz theme_get()w konsoli, aby zobaczyć inne edytowalne atrybuty legendy.


12
Dzięki za sugestię i link do bloga Koshke! Niestety wydaje się, że zmienia to rozmiar pudełek, ale nie odstępy między elementami.
— przeleciał

Możesz to „udawać” za pomocą jakiegoś nakładającego się grobu. Ale nie sądzę, aby istniał sposób na uzyskanie dodatkowego odstępu w legendzie. To jedyna wzmianka o tym, jaką udało mi się znaleźć na liście mailingowej ggplot2: groups.google.com/forum/?fromgroups#!topic/ggplot2/PhkJpP8zJuM
— Brandon Bertelsen

2
Mogę to wykorzystać, aby skutecznie zwiększyć odstępy między legendami. Użycie liczb ujemnych pomogło zmniejszyć odstępy między legendami.
— Nova

5

Użyj dowolnego z nich

legend.spacing = unit(1,"cm")
legend.spacing.x = unit(1,"cm")
legend.spacing.y = unit(1,"cm")
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.