有没有办法在ggplot2中更改图例项之间的间距?

ove*_*ame 108 r legend ggplot2

有没有办法在ggplot2中更改图例项之间的间距?我现在有

legend.position ="top" 
Run Code Online (Sandbox Code Playgroud)

它会自动生成水平图例.然而,物品的间距非常接近,我想知道如何将它们分开更远.

Tun*_*ung 72

ggplot2 v3.0.02018年7月发布的工作选项有修改legend.spacing.x,legend.spacing.ylegend.text.

示例:增加图例键之间的水平间距

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'))
Run Code Online (Sandbox Code Playgroud)

注意:如果您只想展开图例文本右侧的间距,请使用 stringr::str_pad()

示例:将图例键标签移动到底部并增加垂直间距

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)) 
Run Code Online (Sandbox Code Playgroud)

示例:for 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)) 
Run Code Online (Sandbox Code Playgroud)


对于垂直图例,设置legend.key.size仅增加图例键的大小,而不是它们之间的垂直空间

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"))
Run Code Online (Sandbox Code Playgroud)

为了增加图例键之间的距离,需要修改legend-draw.r功能.有关详细信息,请参阅此问题

# 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)
Run Code Online (Sandbox Code Playgroud)

  • 感谢您指出了这一点。这是一个很棒的新功能,我一直在使用@ user2568648的dirty-fix,哈哈! (3认同)
  • 您增加图例键之间的垂直间距的功能是我发现的唯一解决方案,它完全按照我的意愿工作并且易于使用。谢谢! (3认同)
  • 我不断回到这个线程:D 在当前的 ggplot2 中,我们可以(也许应该?)使用 key_glyph 参数,而不是永久覆盖 GeomBar 对象: `geom_bar(..., key_glyph = "polygon3" )` (2认同)

ags*_*udy 62

我认为最好的选择是在guide_legend内部使用guides:

p + guides(fill=guide_legend(
                 keywidth=0.1,
                 keyheight=0.1,
                 default.unit="inch")
      )
Run Code Online (Sandbox Code Playgroud)

注意使用default.unit,不需要加载grid包.

  • 正如Mushin所说,这与其他答案一样,如果图例是**垂直**,则会忽略这一点,它会延伸图例键(例如线段),而不会填充键之间的空间. (8认同)
  • 这可能适用于横向传说.但是,对于我在绘图右侧的垂直图例,这只会增加键的高度,而不是键之间的间距.我的传奇键仍然非常接近. (7认同)
  • 这不适用于geom_bar图表 (3认同)
  • 这需要更多的投票,其他答案已经过时。 (2认同)

use*_*648 44

我用来在水平图例中添加空格的简单修复,只需在标签中添加空格(参见下面的摘录):

  scale_fill_manual(values=c("red","blue","white"),
                    labels=c("Label of category 1          ",
                             "Label of category 2          ",
                             "Label of category 3"))
Run Code Online (Sandbox Code Playgroud)

  • 到目前为止,这是唯一一个处理问题的答案!这可能对许多条目有用:`scale_fill_manual(values = values,labels = setNames(paste(labels,""),entries))`. (13认同)
  • 从技术上讲不是很好,尤其是当您必须将这些空间引入因子级别时,但这是唯一可行的解​​决方案。 (2认同)
  • 或者我们可以使用[str_pad](/sf/answers/3561958571/)来简化生活 (2认同)

Pop*_*Pop 34

现在,optsggplot2包中不推荐使用,theme应该使用函数:

library(grid) # for unit()
... + theme(legend.key.height=unit(3,"line"))
... + theme(legend.key.width=unit(3,"line"))
Run Code Online (Sandbox Code Playgroud)

  • 该解决方案改变了盒子的高度/宽度,而不是它们之间的间距. (16认同)

jcb*_*jcb 18

要在图例中的条目之间添加间距,请调整主题元素的边距legend.text.

要在每个图例标签的右侧添加30pt的空间(可能对水平图例有用):

p + theme(legend.text = element_text(
    margin = margin(r = 30, unit = "pt")))
Run Code Online (Sandbox Code Playgroud)

要在每个图例标签的左侧添加30pt的空间(可能对垂直图例有用):

p + theme(legend.text = element_text(
    margin = margin(l = 30, unit = "pt")))
Run Code Online (Sandbox Code Playgroud)

一个ggplot2对象p.关键字是legend.textmargin.

[关于编辑的注意事项:当这个答案首次发布时,有一个错误.该错误现已修复]

  • 如果您想在每个条目底部和顶部的垂直图例中的项目之间添加空间,请尝试“margin = margin(t = 5, b = 5, unit = "pt")”之类的内容。 (4认同)
  • 该错误现已得到修复,这应该是公认的答案. (3认同)

Bra*_*sen 12

来自Koshke关于ggplot2的工作和他的博客(Koshke的博客)

... + theme(legend.key.height=unit(3,"line")) # Change 3 to X
... + theme(legend.key.width=unit(3,"line")) # Change 3 to X
Run Code Online (Sandbox Code Playgroud)

theme_get()在控制台中键入以查看其他可编辑的图例属性.

  • 感谢您对Koshke博客的建议和链接!不幸的是,这似乎改变了盒子的大小,但没有改变物品之间的间距. (12认同)
  • 我可以用它来成功增加图例之间的间距.使用负数有助于减少图例之间的间距. (2认同)

the*_*ist 7

看起来最好的方法(在2018年)是legend.key.sizetheme对象下使用。(例如,参见此处)。

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

    gp <- ggplot(data = mtcars, aes(mpg, cyl, colour = factor(cyl))) +
        geom_point()
Run Code Online (Sandbox Code Playgroud)

如果您正在使用,确实很容易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)
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

但是,这在其他情况下效果不佳(例如,如果您需要图例符号上的灰色背景):

  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
Run Code Online (Sandbox Code Playgroud)

请注意,白色方块开始阻止图例标题(如果我们继续增加该值,则最终会变成图形本身)。

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

在此处输入图片说明

我还没有找到解决上述问题的解决方法...如果您有想法,请在评论中告诉我,我会相应地进行更新!

  • 我想知道是否有某种方法可以使用$layers...

  • 在我看来,这是最直接、最容易使用的答案 (2认同)

Maa*_*n47 6

使用这些中的任何一个

legend.spacing = unit(1,"cm")
legend.spacing.x = unit(1,"cm")
legend.spacing.y = unit(1,"cm")
Run Code Online (Sandbox Code Playgroud)

  • 我的问题是,图例的标签最终占据了额外空白的中间部分,而不是在图例的彩色框之间生成空间。我发现这里提供的关于“主题(legend.text)”下的填充的答案是最令人满意的。 (2认同)