R ggplot2,顶部和边缘的图例

R ggplot2,顶部和边缘的图例,r,graphics,ggplot2,R,Graphics,Ggplot2,考虑以下几点: library(ggplot2) library(grid) ggplot(diamonds, aes(clarity, fill=cut)) + geom_bar() + theme( plot.margin=unit(x=c(0,0,0,0),units="mm"), legend.position="top", plot.background=element_rect(fill="red")) + guides(fill=guid

考虑以下几点:

library(ggplot2)
library(grid)
ggplot(diamonds, aes(clarity, fill=cut)) + 
  geom_bar() +   
  theme(
    plot.margin=unit(x=c(0,0,0,0),units="mm"),
    legend.position="top",
    plot.background=element_rect(fill="red")) +
  guides(fill=guide_legend(title.position="top"))
p + guides(fill=guide_legend(keyheight=unit(1,"cm"))) + theme(plot.margin=unit(c(1,1,1,1),"cm"))
showViewport(col="black",label=TRUE, newpage=TRUE, leaves=FALSE)
其输出如下所示: 在
plot.margin=unit(x=c(0,0,0,0),units=“mm”)
的上下文中,图例上方有大量不合适的白色(红色)空间。有人知道如何补救吗

谢谢你的提示


诚恳地说,就像你说的,我在你的例子中看不到,但我猜边缘是传说本身。通过添加以下内容,可以消除图例本身周围的边距:

+ theme(legend.margin=margin(t = 0, unit='cm'))
这适用于ggplot2 v2.1.0或更高版本。请注意,至少就目前而言,旧的解决方案仍然有效:

+ theme(legend.margin=unit(-0.6,"cm")) # version 0.9.x

如果我为了更高的可视性而放大边距,并运行ShowViewport,我会得到以下结果:

library(ggplot2)
library(grid)
ggplot(diamonds, aes(clarity, fill=cut)) + 
  geom_bar() +   
  theme(
    plot.margin=unit(x=c(0,0,0,0),units="mm"),
    legend.position="top",
    plot.background=element_rect(fill="red")) +
  guides(fill=guide_legend(title.position="top"))
p + guides(fill=guide_legend(keyheight=unit(1,"cm"))) + theme(plot.margin=unit(c(1,1,1,1),"cm"))
showViewport(col="black",label=TRUE, newpage=TRUE, leaves=FALSE)

从中可以看出,这个不存在的标题以某种方式占据了空间

编辑:不,这只是不幸的标签重叠。这不是标题

让我们看看传说本身,这似乎是造成问题的原因

library(gtable)
g = ggplotGrob(p)
leg = gtable_filter(g, "guide")
plot(leg)
leg$heights
# sum(0.5lines, sum(1.5mm, 10mm, 0mm, 1.5mm), 0.5lines)+0cm
grid.rect(height=leg$heights) 
grid.rect(height=leg$heights - unit(1,"line"), gp=gpar(lty=2))
因此,事实上,正是图例增加了一些边距(0.5+0.5=1行)。我想这是一个缺少的
指南。margin
,它被半行的默认值所取代


在该问题被询问/回答后的一年内,ggplot进入了维护模式,因此未来不会有任何更新(意味着OP将无法工作)

公认的答案依赖于用
legend.margin
在图例周围伪造边距。但是,这并不能很好地推广,尤其是在使用具有不同大小或比例因子的
ggsave()
时。不过,幸运的是,有一个更具普遍性的解决方案

legend.margin
对所有边的填充仅采用一个值,而
plot.margin
对顶部、右侧、底部和左侧边距采用四个值。默认边距基于线条(而不是毫米或英寸),例如:
plot.margin=unit(c(c(1,1,0.5,0.5)),units=“line”)

如果将
legend.margin
设置为0,则可以基于线单位使用负值
plot.margin
值将图例移动到绘图区域的边缘。将上边距设置为-0.5非常有效:

ggplot(diamonds, aes(clarity, fill=cut)) + 
  geom_bar() +   
  theme(
    plot.margin=unit(c(-0.5, 1, 0.5, 0.5), units="line"),
    legend.position="top",
    plot.background=element_rect(fill="red"),
    legend.margin=unit(0, "lines")) +
  guides(fill=guide_legend(title.position="top"))

如果图例位于底部,同样的想法也适用:

ggplot(diamonds, aes(clarity, fill=cut)) + 
  geom_bar() +   
  theme(
    plot.margin=unit(c(1, 1, -0.5, 0.5), units="line"),
    legend.position="bottom",
    plot.background=element_rect(fill="red"),
    legend.margin=unit(0, "lines")) +
  guides(fill=guide_legend(title.position="top"))


只要将感兴趣的边距设置为-0.5行,多余的空白就应该消失。这应该适用于任何视口大小和任何宽度/高度/比例组合,并使用
ggsave()

,面板也有边距(
panel.margin
)将all设置为零仍然会在顶部留下一些额外的空间。如果您坚持要消除这些,您可以将负数作为
unit
s传递,例如:
theme(plot.margin=unit(x=c(-5,0,0,0),units=“mm”)
更改了示例中的背景以说明该问题。无论是
面板.页边距
还是
图例.页边距
都没有任何效果。我知道这并不是解决问题的精确方法,但为什么不将图例放在绘图窗口中呢?如果绘图窗口中的某个地方有大量可用空间,您可以将图例放在那里。在这个示例数据集中,
theme(legend.position=c(0.9,0.8))
将图例放在右上角。@sc_evans
unit(-1,“line”)
根据我下面的调查,可能更接近事实。这更改为
theme(legend.margin=margin(t=-0.5,unit='cm'))
Hmmm…无论是将标题显式设置为NULL还是将其元素的大小和/或行高设置为0都不会带来任何好处…还有其他想法吗?我走错了方向。我添加了更多提示,现在指向图例。并发布了@baptiste:你知道如何将图例标题包装为两行吗?好问题,刚刚丢失一个小时后,我试图找出0的legend.margin似乎不起作用的原因。爱/恨ggplot关系继续!虽然此解决方案确实缩短了legend和“顶”视口边框之间的距离,但使legend更接近主绘图似乎是不可能的。我试图修改参数,但无法达到解决方案n在2.1.0之前有效。
legend.key.height=unit(0,“cm”)
缩短了距离,适用于顶部/底部图例,但仍保留了由某些内容引入的小间隙。