首页 文章

ggplot:“大小健壮”的方式将水平图例放在右下角

提问于
浏览
2

我试图在绘图区域外的右下角放置一个水平图例 .

我意识到这已经讨论过了 . 然而,经过长时间令人沮丧的早晨,我无法达到“尺寸稳健”的解决方案 .

以下是我发现的3种解决方案:

  • 当我将 legend.position 设置为 bottom 时:图例位于底部中心,但我无法使用 legend.justification 将其推向右侧

  • 当我将 legend.position 设置为 c(1,0) 时:图例位于右下角 . 但是,图例放在图中 .

  • 当我添加 plot.margin 并向下推 legend.position 时:图例位于图的右下角和外部 . 但是,当我更改绘图区域的大小时,图例不再正确定位 .

第三种解决方案的定位不正确:

enter image description here

enter image description here


Reproducible code:

# Generate random data------

sample.n = 50
sample.data = data.frame(x = runif(sample.n,0,1), y = runif(sample.n,0,1), value = runif(sample.n,0,10))

# Plot ------

library(ggplot2)

# Margins are fine. And If I change the size of the plotting area, the legend will always be bottom- centered
# Problem: Can't push it to the right side  
ggplot(sample.data, aes(x = x, y = y, color = value)) + geom_point() + 
  theme(legend.direction = "horizontal", legend.position = "bottom") 

# Pushed to the bottom-right Successfully 
# Problem: Legend inside the plot
ggplot(sample.data, aes(x = x, y = y, color = value)) + geom_point() + 
  theme(legend.direction = "horizontal",legend.position = c(1,0)) # Problem: inside plot 

# Placed at the bottom-right corner outside the plot region 
# Problem: If I change the size of the plotting region, the legend will not be cornred
ggplot(sample.data, aes(x = x, y = y, color = value)) + geom_point() + 
  theme(legend.direction = "horizontal", legend.position = c(0.9,-0.2),  
        plot.margin = unit(c(1, 1, 5, 1), "lines"))

Theme-Legend的文档:

legend.position传奇的位置(“无”,“左”,“右”,“底部”,“顶部”或双元素数字向量)legend.justification锚点,用于在图中定位图例(“中心”)或双元素数值向量)

1 回答

  • 3

    Edit 使用2.2.0,可以使用主题中的 legend.justificationlegend.margin 将图例推到右侧 .

    # Generate random data------
    
    sample.n = 50
    sample.data = data.frame(x = runif(sample.n,0,1), y = runif(sample.n,0,1), value = runif(sample.n,0,10))
    
    # Plot ------
    
    library(ggplot2)
    library(gtable)
    library(grid)
    
    p = ggplot(sample.data, aes(x = x, y = y, color = value)) + geom_point() + 
      theme(legend.direction = "horizontal", legend.position = "bottom",
              legend.box.background = element_rect(colour = "black"))
    
    p + theme(legend.justification = "right",
              legend.margin = margin(t = 2, r = 0, b = 2, l = 2, unit = "mm"))
    

    enter image description here


    为了它的 Value ,我留下原来的答案,但更新到ggplot版本2.2.0 .

    我在这里做的是从绘图中提取图例,将图例包装在视口中,以便视口位于右侧,将图例放回到绘图中,并删除原始图例 .

    # Generate random data------
    
    sample.n = 50
    sample.data = data.frame(x = runif(sample.n,0,1), y = runif(sample.n,0,1), value = runif(sample.n,0,10))
    
    # Plot ------
    
    library(ggplot2)
    library(gtable)
    library(grid)
    
    p = ggplot(sample.data, aes(x = x, y = y, color = value)) + geom_point() + 
      theme(legend.direction = "horizontal", legend.position = "bottom")
    
    # Get the ggplot grob
    g = ggplotGrob(p)
    
    # Get the legend
    index = which(g$layout$name == "guide-box")
    leg = g$grobs[[index]]
    
    # Wrap the legend in a viewport
    leg$vp = viewport(x = unit(1, "npc"), width = sum(leg$widths), just = "right")
    
    ### Put the legend back into the plot
         # First, get the current location of the legend
    pos = g$layout[index, ]
    g = gtable_add_grob(g, leg, t = pos$t, l = pos$l)
    
    # Remove the original legend
    g$grobs <- g$grobs[-index]
    g$layout <- g$layout[-index, ]
    
    # Draw the chart
    grid.newpage()
    grid.draw(g)
    

    enter image description here

    请注意,图例已向右移动,但图例的右边缘与绘图面板的右边缘不完全对齐 . 这是因为图例有内部边距 . 图例本身有边距,但边距设置为0 mm . 要使图例与绘图面板对齐,需要更多的摆弄 . 在下文中,内部边距(和图例边距)设置为0.此外,图例和图例的内部部分包含在右对齐视口中 .

    # Get the ggplot grob
    g = ggplotGrob(p)
    
    # Get the legend
    index = which(g$layout$name == "guide-box")
    leg = g$grobs[[index]]
    
    # Remove the legend right margin and an internal margin
    leg$widths[4] = unit(0, "mm")
    leg$grobs[[1]]$widths[5] = unit(0, "mm")
    
    # Wrap the legend in a viewport
    leg$vp = viewport(x = unit(1, "npc"), width = sum(leg$widths), just = "right")
    
    # Wrap the internal part of the legend in a right justified viewport
    leg$grobs[[1]]$vp = viewport(x = unit(1, "npc"), width = sum(leg$grobs[[1]]$widths), just = "right")
    
    ### Put the legend back into the plot
         # First, get the current location of the legend
    pos = g$layout[index, ]
    g = gtable_add_grob(g, leg, t = pos$t, l = pos$l)
    
    # Remove the original legend
    g$grobs <- g$grobs[-index]
    g$layout <- g$layout[-index, ]
    
    # Draw the chart
    grid.newpage()
    grid.draw(g)
    

    enter image description here

相关问题