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

时间:2016-07-06 11:15:12

标签: r ggplot2 legend

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

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

以下是我找到的3个解决方案:

  • 当我将legend.position设置为bottom时:图例位于 底部中心,但我没有使用它将其推向右侧 legend.justification
  • 当我将legend.position设置为c(1,0)时:图例位于 右下角。但是,图例放在图中。
  • 当我添加plot.margin并进一步向下推legend.position时: 图例位于图的右下角和外部。但是,当我更改绘图区域的大小时,图例不再正确定位。


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

enter image description here enter image description here

可重现的代码:

# 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 传说的位置(“无”,“左”,“右”,   “bottom”,“top”或双元素数字向量)

     

legend.justification 用于在图块内定位图例的锚点   (“中心”或双元素数字向量)

1 个答案:

答案 0 :(得分:3)

修改使用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

对于它的价值,我留下原始答案,但更新到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