【问题标题】:ggplot2: center legend below plot instead of panel areaggplot2:图下方的中心图例而不是面板区域
【发布时间】:2014-08-02 22:41:09
【问题描述】:

ggplot 默认情况下,面板下方的图例居中,这在某些情况下确实令人沮丧。请看下面的例子:

ggplot(diamonds, aes(cut, fill = clarity)) + geom_bar() + coord_flip() + 
  theme(legend.position = 'bottom')

可以看出,最后一个标签是从图像中裁剪出来的,尽管我们在图例的左侧有一些空白——使用它会更好。

问:我怎样才能使图例居中在图下方,而不是试图强迫它居中在面板区域下方来克服这个问题?


更新:关于此问题的更多示例:

df <- data.frame(
    x = sample(paste('An extremely long category label that screws up legend placement', letters[1:7]), 1e3, TRUE),
    y = sample(paste('Short label', letters[1:7]), 1e3, TRUE)
    )

ggplot(df, aes(x, fill = y)) + geom_bar() + coord_flip() +
  theme(legend.position = 'bottom')


我做了什么:我可以使用legend.direction 手动将图例放在面板下方并在绘图下方添加一些额外的边距,例如:

ggplot(diamonds, aes(cut, fill = clarity)) + geom_bar() + coord_flip() + 
  theme(legend.position  = c(0.37, -0.1),
        legend.direction = 'horizontal',
        plot.margin      = grid::unit(c(0.1,0.1,2,0.1), 'lines'))

但这样我必须“手动”计算最佳legend.position。有什么建议吗?


更新:我将多个绘图并排排列,因此我不想将图例放在实际图像的中心,而是放在单个面板上。例如:

p1 <- ggplot(diamonds, aes(cut)) + geom_histogram()
p2 <- ggplot(diamonds, aes(cut, fill = clarity)) + geom_bar() + coord_flip() +
  theme(legend.position = 'bottom')
pushViewport(viewport(layout = grid.layout(nrow = 1, ncol = 2, widths = unit(c(1, 2), c("null", "null")))))
print(p1, vp = viewport(layout.pos.row = 1, layout.pos.col = 1))
print(p2, vp = viewport(layout.pos.row = 1, layout.pos.col = 2))

【问题讨论】:

  • 不是移动文本,你不能增加右边距,这样它就不会切断你的文本吗? plot.margin = grid::unit(c(0.1,10,2,0.1), 'lines') 原来的情节在我的窗口中渲染得很好,所以我看不到这是否有效。
  • @Reed 谢谢,但我不能。甚至更多:这个问题是由于情节的宽度是有限的。想象一下,如果cut 的类别更长。我会尝试提出一些更相关的例子。

标签: r ggplot2 legend


【解决方案1】:

我一直在寻找解决此问题的方法,并意识到我可以使用Claus Wilke 的cowplot 将绘图拆分为网格。这有点小技巧,但很容易。

df <- data.frame(
  x = sample(paste('An extremely long category label that screws up legend placement', letters[1:7]), 1e3, TRUE),
  y = sample(paste('Short label', letters[1:7]), 1e3, TRUE)
)

首先让我们将原始图保存到一个对象中:

p1 <- ggplot(df, aes(x, fill = y)) + geom_bar() + coord_flip() +
  theme(legend.position = 'bottom')

接下来我们将保存另一个没有图例的版本,并使用cowplot的get_legend()保存图例:

p2 <- p1 + theme(legend.position = "none")
le1 <- cowplot::get_legend(p1)

画出情节。

cowplot::plot_grid(p2, le1, nrow = 2, rel_heights = c(1, 0.2))

【讨论】:

    【解决方案2】:

    您可以编辑 gtable,

    library(gtable)
    
    g <- ggplotGrob(p)
    id <- which(g$layout$name == "guide-box")
    g$layout[id, c("l","r")] <- c(1, ncol(g))
    grid.newpage()
    grid.draw(g)
    

    【讨论】:

    • 太棒了(+1),谢谢@baptiste。在接受您的回答之前,我仍然会再等待几天其他替代解决方案,因为我目前正在安排多个图并排在一起(请参阅更新的问题),所以我不想将图例集中在图形设备,但在绘图区域上。
    猜你喜欢
    • 1970-01-01
    • 2012-10-20
    • 2017-06-23
    • 2015-12-15
    • 1970-01-01
    • 2022-01-18
    • 1970-01-01
    • 2013-08-06
    • 1970-01-01
    相关资源
    最近更新 更多