【问题标题】:ggplot2 legend width and legend strings sizeggplot2图例宽度和图例字符串大小
【发布时间】:2025-12-29 18:00:11
【问题描述】:

我有两个完全相同的图,除了填充条的颜色在每个图上都不同。由于不同图上的图例因其名称的大小而具有不同的宽度,因此每个图上的图形和图例之间的比率会有所不同。我需要让两者看起来一样。

这是一个例子:

library(ggplot2)

x = c(rep("a",20),rep("b",10))
y = c(x = c(rep("BIGTEXT",20),rep("EVENBIGGERTEXT",10)))
df = data.frame(x,y)

p1 = ggplot(df,aes(x,fill=x)) + geom_bar()
p2 = ggplot(df,aes(y,fill=y)) + geom_bar()

p1
p2

【问题讨论】:

    标签: r ggplot2 legend legend-properties


    【解决方案1】:

    您可以将 gtable 宽度设置为一个通用值,

    library(gtable)
    library(grid)
    gl <- lapply(list(p1, p2), ggplotGrob)
    
    gwidth <- do.call(unit.pmax, lapply(gl, "[[", "widths"))
    gl <- lapply(gl, "[[<-", "widths", value = gwidth)
    gridExtra::grid.arrange(grobs=gl)
    

    或者,您可以将set the panel size 设置为固定值。

    【讨论】:

    • 非常优雅,但这导致图例之间的图例键位置略有不同。有没有办法强制将宽度等同于图例 gtable?
    • @user20650 这当然是可能的,但有点繁琐,因为 i) 整个事情的文档记录很差(人们可能期望 legend.marginlegend.justification 对此有所帮助,但没有),ii) ggplot 保持随着时间的推移改变其布局结构; iii) gtable 从来没有以方便的方式解决理由,需要越来越深的嵌套 gtables 难以导航。这个问题不是针对这个问题的,所以我不确定预期的用例是什么。
    【解决方案2】:

    跟进@baptiste 的评论:虽然很麻烦,但可以做到。但不能保证这将在未来的版本中起作用。解决方案取自 here,但该解决方案也需要更新。

    library(ggplot2)   # v2.2.1
    library(gtable)    # v0.2.0
    library(grid)
    library(gridExtra) # v2.2.1
    
    x = c(rep("a",20),rep("b",10))
    y = c(x = c(rep("BIGTEXT",20),rep("EVENBIGGERTEXT",10)))
    df = data.frame(x,y)
    
    p1 = ggplot(df,aes(x,fill=x)) + geom_bar()
    p2 = ggplot(df,aes(y,fill=y)) + geom_bar()
    
    # Get the grobs
    gA <- ggplotGrob(p1)
    gB <- ggplotGrob(p2)
    
    # Get the widths of the legends
    index = which(gA$layout$name == "guide-box")
    leg1 <- convertX(sum(with(gA$grobs[[index]], grobs[[1]]$widths)), "mm")
    leg2 <- convertX(sum(with(gB$grobs[[index]], grobs[[1]]$widths)), "mm")
    
    # Add an empty column of width "abs(diff(c(leg1, leg2))) mm" to the right of 
    # legend box for gA (the smaller legend box)
    gA$grobs[[index]] <- gtable_add_cols(gA$grobs[[index]], unit(abs(diff(c(leg1, leg2))), "mm"))
    
    # Set widths to maximums of corresponding widths
    gl <- list(gA, gB)
    gwidth <- do.call(unit.pmax, lapply(gl, "[[", "widths"))
    gl <- lapply(gl, "[[<-", "widths", value = gwidth)
    
    
    # Draw the plots
    grid.newpage()
    grid.draw(gl[[1]])
    
    grid.newpage()
    grid.draw(gl[[2]])
    

    【讨论】:

      最近更新 更多