Gibt es eine Möglichkeit, den Abstand zwischen Legendenelementen in ggplot2 zu ändern?

120

Gibt es eine Möglichkeit, den Abstand zwischen Legendenelementen in ggplot2 zu ändern? Ich habe derzeit

legend.position ="top" 

Dies erzeugt automatisch eine horizontale Legende. Der Abstand der Elemente ist jedoch sehr eng beieinander und ich frage mich, wie ich sie weiter auseinander platzieren kann.

Überlaufname
quelle
Es wäre nützlich, jetzt eine aktuelle Lösung dafür zu haben, optsdie abgeschrieben wird.
Geotheory
Hier: pastebin.com/NnxMiTeH
PatrickT
3
Tungs Antwort, die sich derzeit am Ende dieses Threads befindet, wurde im Juli 2018 aktualisiert. Fehler wurden behoben und hackige Problemumgehungen wie die im Pastebin oben werden nicht mehr benötigt.
PatrickT

Antworten:

90

ggplot2 v3.0.0veröffentlicht im Juli 2018 hat Arbeitsoptionen zu ändern legend.spacing.x, legend.spacing.yund legend.text.

Beispiel: Erhöhen Sie den horizontalen Abstand zwischen den Legendenschlüsseln

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'))

Hinweis: Wenn Sie nur den Abstand rechts vom Legendentext erweitern möchten, verwenden Sie stringr::str_pad()

Beispiel: Verschieben Sie die Beschriftungen der Legendenschlüssel nach unten und vergrößern Sie den vertikalen Abstand

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)) 

Beispiel: für 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)) 


Bei vertikalen Legendenlegend.key.size vergrößert die Einstellung nur die Größe der Legendenschlüssel, nicht den vertikalen Abstand zwischen ihnen

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"))

Um den Abstand zwischen den Legendentasten zu vergrößern, muss die legend-draw.rFunktion geändert werden . Weitere Informationen finden Sie in dieser Ausgabe

# 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)

Tung
quelle
3
Vielen Dank für den Hinweis. Dies ist eine großartige neue Funktion. Ich habe immer @ user2568648s Dirty-Fix ​​verwendet, haha!
Tjebo
1
Ihre Funktion zum Erhöhen des vertikalen Abstands zwischen Legendenschlüsseln ist die einzige Lösung, die ich gefunden habe und die genau nach meinen Wünschen und mit einfacher Bedienung funktioniert. Vielen Dank!
Docconcoct
69

Ich denke, die beste Option ist, guide_legendinnerhalb von zu verwenden guides:

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

Beachten Sie die Verwendung von default.unit, kein gridPaket muss geladen werden.

Agstudy
quelle
2
Dies erfordert mehr Upvotes, die anderen Antworten sind veraltet.
Brandon Bertelsen
8
Dies kann für horizontale Legenden funktionieren. Für meine vertikale Legende rechts neben dem Plot erhöht dies jedoch nur die Höhe des Schlüssels, nicht den Abstand zwischen den Schlüsseln. Meine Legendenschlüssel sind immer noch sehr nahe beieinander.
Muhsin Zahid Ugur
9
Wie Mushin sagt, verfehlt dies den Punkt, wie bei anderen Antworten. Wenn die Legende VERTIKAL ist , werden die Legendenschlüssel (z. B. die Liniensegmente) gedehnt, ohne den Abstand zwischen den Tasten aufzufüllen.
PatrickT
Funktioniert gut mit geom_line und geom_point zusammen.
Niels Holst
45

Eine einfache Korrektur, die ich verwende, um Platz in horizontalen Legenden hinzuzufügen. Fügen Sie einfach Leerzeichen in die Beschriftungen ein (siehe Auszug unten):

  scale_fill_manual(values=c("red","blue","white"),
                    labels=c("Label of category 1          ",
                             "Label of category 2          ",
                             "Label of category 3"))
user2568648
quelle
13
Dies ist die einzige Antwort, die sich bisher mit der Frage befasst! Dies kann bei vielen Einträgen hilfreich sein : scale_fill_manual(values=values, labels=setNames(paste(labels, " "), entries)).
SaschaH
2
Technisch nicht sehr schön, besonders wenn Sie diese Räume in Faktorstufen einführen müssen, aber es ist die einzige funktionierende Lösung dafür.
Patrick Bucher
2
Oder wir können str_pad verwenden , um das Leben ein bisschen einfacher zu machen
Tung
37

Nun, das optsist in ggplot2Paket, Funktion veraltettheme sollte stattdessen die verwendet werden:

library(grid) # for unit()
... + theme(legend.key.height=unit(3,"line"))
... + theme(legend.key.width=unit(3,"line"))
Pop
quelle
18
Diese Lösung ändert die Höhe / Breite der Boxen im Gegensatz zum Abstand zwischen ihnen.
Berk U.
24

Passen Sie die Ränder des Designelements an, um den Abstand zwischen Einträgen in einer Legende zu erhöhen legend.text.

So fügen Sie rechts neben jeder Legendenbezeichnung 30pt Platz hinzu (kann für eine horizontale Legende nützlich sein):

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

So fügen Sie links neben jeder Legendenbezeichnung 30pt Platz hinzu (kann für eine vertikale Legende nützlich sein):

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

für ein ggplot2Objekt p. Die Schlüsselwörter sind legend.textundmargin .

[Hinweis zum Bearbeiten: Als diese Antwort zum ersten Mal veröffentlicht wurde, gab es einen Fehler. Der Fehler wurde jetzt behoben]

jcb
quelle
3
Der Fehler wurde nun behoben, dies sollte die akzeptierte Antwort sein.
Giocomai
1
Siehe auch Tungs Antwort für ein Update im Juli 2018 zu diesen Themen.
PatrickT
17

Der beste Ansatz (im Jahr 2018) ist die Verwendung legend.key.sizeunter dem themeObjekt. (siehe zB hier ).

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

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

Dies ist ganz einfach, wenn Sie Folgendes verwenden 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)

Geben Sie hier die Bildbeschreibung ein

Dies funktioniert jedoch ansonsten nicht ganz so gut (z. B. wenn Sie den grauen Hintergrund auf Ihrem Legenden-Symbol benötigen):

  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

Beachten Sie, dass weiße Quadrate den Legendentitel blockieren (und schließlich das Diagramm selbst, wenn wir den Wert weiter erhöhen).

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

Geben Sie hier die Bildbeschreibung ein

Ich habe noch keine Lösung gefunden, um das oben genannte Problem zu beheben ... Lassen Sie mich in den Kommentaren wissen, wenn Sie eine Idee haben, und ich werde sie entsprechend aktualisieren!

  • Ich frage mich, ob es eine Möglichkeit gibt, Dinge mit $layers...
der Waldökologe
quelle
Machen Sie das legend.keytransparent:theme(legend.key = element_rect(size = 30,color=alpha("transparent",0)))
Ukosteopath
1
Dies war die einfachste Antwort und am einfachsten zu verwenden imo
Blacklivesmatter
14

Aus Koshkes Arbeit an ggplot2 und seinem Blog ( Koshkes Blog )

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

Geben Sie theme_get()die Konsole ein, um andere bearbeitbare Legendenattribute anzuzeigen.

Brandon Bertelsen
quelle
12
Danke für den Vorschlag und den Link zu Koshkes Blog! Leider scheint dies jedoch die Größe der Kästchen zu ändern, nicht jedoch den Abstand zwischen den Elementen.
Überlaufname
Möglicherweise können Sie es mit einer Art Overlaying-Grob "fälschen". Aber ich denke nicht, dass es einen Weg gibt, innerhalb der Legende zusätzlichen Abstand zu bekommen. Dies ist die einzige Erwähnung, die ich in der Mailingliste von ggplot2
Brandon Bertelsen
2
Ich kann dies verwenden, um den Abstand zwischen Legenden erfolgreich zu vergrößern. Die Verwendung negativer Zahlen trug dazu bei, den Abstand zwischen Legenden zu verringern.
Nova
5

Verwenden Sie eines davon

legend.spacing = unit(1,"cm")
legend.spacing.x = unit(1,"cm")
legend.spacing.y = unit(1,"cm")
MaazKhan47
quelle