Existe uma maneira de alterar o espaçamento entre os itens de legenda no ggplot2?


120

Existe uma maneira de alterar o espaçamento entre os itens de legenda no ggplot2? Eu atualmente tenho

legend.position ="top" 

que produz automaticamente uma legenda horizontal. No entanto, o espaçamento dos itens é muito próximo e estou me perguntando como espaçá-los ainda mais.


Seria útil ter uma solução atual para isso agora que optsestá depreciado.
— geotheory


3
A resposta de Tung, atualmente no final deste tópico, tem uma atualização de julho de 2018. Bugs foram corrigidos e soluções alternativas como a do pastebin acima não são mais necessárias.
— PatrickT

Respostas:


90

ggplot2 v3.0.0lançado em julho 2018 tem opções de trabalho para modificar legend.spacing.x, legend.spacing.ye legend.text.

Exemplo: aumentar o espaçamento horizontal entre as chaves da legenda

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

Nota: Se você deseja apenas expandir o espaçamento à direita do texto da legenda, use stringr::str_pad()

Exemplo: mova os rótulos das teclas de legenda para a parte inferior e aumente o espaçamento vertical

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

Exemplo: para 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)) 


Para legendas verticais , a configuração legend.key.sizeapenas aumenta o tamanho das chaves da legenda, não o espaço vertical entre elas

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

Para aumentar a distância entre as teclas de legenda, legend-draw.ré necessária a modificação da função. Veja este problema para mais informações

# 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
Obrigado por apontar isso. Este é um novo recurso tão bom, eu sempre estava usando a correção suja de @ user2568648, haha!
— Tjebo

1
Sua função de aumentar o espaçamento vertical entre as teclas de legenda é a única solução que encontrei que funciona exatamente como desejo e com facilidade de uso. Obrigado!
— Docconcoct

69

Acho que a melhor opção é usar guide_legendem guides:

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

Observe o uso de default.unit, sem necessidade de carregar o gridpacote.


2
Isso precisa de mais votos positivos, as outras respostas estão desatualizadas.
— Brandon Bertelsen

8
Isso pode funcionar para legendas horizontais. No entanto, para minha legenda vertical à direita do gráfico, isso apenas aumenta a altura da chave, não o espaçamento entre as chaves. Minhas chaves de legenda ainda estão muito próximas umas das outras.
— Muhsin Zahid Ugur

9
Como diz Mushin, isso perde o ponto, como com outras respostas, se a legenda for VERTICAL, ela estica as teclas da legenda (por exemplo, os segmentos de linha) sem preencher o espaço entre as teclas.
— PatrickT

Funciona bem junto com geom_line e geom_point.
— Niels Holst

45

Uma correção simples que eu uso para adicionar espaço em legendas horizontais, basta adicionar espaços nos rótulos (ver trecho abaixo):

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

13
Esta é a única resposta até agora que trata da questão! Isso pode ser útil em caso de muitas entradas: scale_fill_manual(values=values, labels=setNames(paste(labels, " "), entries)).
— SaschaH de

2
Tecnicamente não é muito bom, especialmente quando você tem que introduzir esses espaços em níveis de fator, mas é a única solução de trabalho para.
— Patrick Bucher

2
Ou podemos usar str_pad para tornar a vida um pouco mais fácil
— Tung

37

Agora que optsestá obsoleto no ggplot2pacote, a função themedeve ser usada em seu lugar:

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

18
Esta solução altera a altura / largura das caixas em oposição ao espaçamento entre elas.
— Berk U.

25

Para adicionar espaçamento entre as entradas em uma legenda, ajuste as margens do elemento do tema legend.text.

Para adicionar 30pt de espaço à direita de cada rótulo de legenda (pode ser útil para uma legenda horizontal):

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

Para adicionar 30pt de espaço à esquerda de cada rótulo de legenda (pode ser útil para uma legenda vertical):

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

para um ggplot2objeto p. As palavras-chave são legend.texte margin.

[Nota sobre a edição: quando esta resposta foi postada pela primeira vez, havia um bug. O bug foi corrigido]


3
O bug foi corrigido, esta deve ser a resposta aceita.
— giocomai

1
Veja também a resposta de Tung para uma atualização de julho de 2018 sobre esses assuntos.
— PatrickT

17

Parece que a melhor abordagem (em 2018) é usar legend.key.sizesob o themeobjeto. (por exemplo, veja aqui ).

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

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

Isso é muito fácil se você estiver usando 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)

insira a descrição da imagem aqui

No entanto, isso não funciona tão bem de outra forma (por exemplo, se você precisar do fundo cinza no símbolo da legenda):

  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

Observe que os quadrados brancos começam a bloquear o título da legenda (e, eventualmente, o próprio gráfico, se continuarmos aumentando o valor).

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

insira a descrição da imagem aqui

Ainda não encontrei uma solução alternativa para corrigir o problema acima ... Deixe-me saber nos comentários se você tiver uma ideia e eu atualizarei de acordo!

  • Eu me pergunto se há alguma maneira de reorganizar as coisas usando $layers...

Faça o legend.keytransparente:theme(legend.key = element_rect(size = 30,color=alpha("transparent",0)))
— ukosteopath

1
esta foi a resposta mais direta e fácil de usar imo
— Blacklivesmatter

14

Do trabalho de Koshke no ggplot2 e seu 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

Digite theme_get()no console para ver outros atributos de legenda editáveis.


12
Obrigado pela sugestão e link para o blog do Koshke! Infelizmente, no entanto, isso parece alterar o tamanho das caixas, mas não o espaçamento entre os itens.
— sobrevoou em

Você pode ser capaz de "falsificá-lo" com algum tipo de grob de sobreposição. Mas não acho que haja uma maneira de obter espaço extra dentro da lenda. Esta é a única menção que pude encontrar na lista de e-mails do ggplot2: groups.google.com/forum/?fromgroups#!topic/ggplot2/PhkJpP8zJuM
— Brandon Bertelsen

2
Posso usar isso para aumentar o espaçamento entre as lendas com sucesso. O uso de números negativos ajudou a diminuir o espaçamento entre as legendas.
— Nova de

5

Use qualquer um destes

legend.spacing = unit(1,"cm")
legend.spacing.x = unit(1,"cm")
legend.spacing.y = unit(1,"cm")
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.