web-dev-qa-db-fra.com

Est-il possible de changer l'espacement entre les éléments de légende dans ggplot2?

Est-il possible de changer l'espacement entre les éléments de légende dans ggplot2? J'ai actuellement

legend.position ="top" 

qui produit automatiquement une légende horizontale. Cependant, l’espacement des éléments est très rapproché et je me demande comment les espacer davantage.

105
overflowname

ggplot2 v3.0.0 publié en juillet 2018 possède des options de travail pour modifier legend.spacing.x, legend.spacing.y Et legend.text.

Exemple: augmentez l'espacement horizontal entre les touches de légende

library(ggplot2)

ggplot(mtcars, aes(factor(cyl), fill = factor(cyl))) + 
  geom_bar() +
  coord_flip() +
  scale_fill_viridis_d("Cyl") +
  theme(legend.position = 'top', 
        legend.spacing.x = unit(1.0, 'cm'))

Remarque: Si vous souhaitez uniquement augmenter l'espacement à droite du texte de la légende, utilisez stringr::str_pad()

Exemple: déplacez les étiquettes de clé de légende vers le bas et augmentez l'espacement vertical

ggplot(mtcars, aes(factor(cyl), fill = factor(cyl))) + 
  geom_bar() +
  coord_flip() +
  scale_fill_viridis_d("Cyl") +
  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)) 

Exemple: pour 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(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)) 


Pour les légendes verticales , le réglage de legend.key.size N'augmente que la taille des clés de légende, pas l'espace vertical entre elles.

ggplot(mtcars) +
  aes(fill = factor(cyl), x = cyl) +
  geom_bar() +
  theme(legend.key.size = unit(1, "cm"))

Afin d'augmenter la distance entre les touches de légende, il est nécessaire de modifier la fonction legend-draw.r. Voir ceci numéro pour plus d'informations

# 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(fill = factor(cyl), x = cyl) +
  geom_bar() +
  theme(legend.key = element_rect(color = NA, fill = NA),
        legend.key.size = unit(1.5, "cm"))

61
Tung

Je pense que la meilleure option est d'utiliser guide_legend dans guides:

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

Notez l'utilisation de default.unit, pas besoin de charger le package grid.

61
agstudy

Un correctif simple que j'utilise pour ajouter de l'espace dans les légendes horizontales, ajoutez simplement des espaces dans les étiquettes (voir extrait ci-dessous):

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

Maintenant que opts est obsolète dans ggplot2 package, fonction theme devrait être utilisé à la place:

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

Pour ajouter un espacement entre les entrées d’une légende, ajustez les marges de l’élément theme legend.text.

Pour ajouter 30 points d’espace à droite de chaque étiquette de légende (cela peut s’avérer utile pour une légende horizontale):

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

Pour ajouter 30 points d’espace à gauche de chaque étiquette de légende (cela peut s’avérer utile pour une légende verticale):

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

pour un ggplot2 objet p. Les mots-clés sont legend.text et margin.

[Remarque à propos de la modification: lorsque cette réponse a été publiée pour la première fois, il y avait un bogue. Le bug a maintenant été corrigé]

17
jcb

Extrait du travail de Koshke sur ggplot2 et de son blog ( blog de Koshke )

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

Tapez theme_get() dans la console pour afficher d'autres attributs de légende modifiables.

11
Brandon Bertelsen

La meilleure approche (en 2018) consiste à utiliser legend.key.size Sous l'objet theme. (par exemple, voir ici ).

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

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

C'est très facile si vous utilisez 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)

enter image description here

Toutefois, cela ne fonctionne pas très bien autrement (par exemple, si vous avez besoin du fond gris sur votre symbole de légende):

  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

Notez que les carrés blancs commencent à bloquer le titre de la légende (et éventuellement le graphique lui-même si nous continuons à augmenter la valeur).

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

enter image description here

Je n'ai pas encore trouvé de solution pour résoudre le problème ci-dessus ... Faites-moi savoir dans les commentaires si vous avez une idée, et je mettrai à jour en conséquence!

  • Je me demande s'il y a un moyen de ré-empiler les choses en utilisant $layers ...
7

Utilisez l'un de ces

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