ggplot2,顶部和边缘的传奇

bal*_*lin 23 graphics r 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=guide_legend(title.position="top"))
Run Code Online (Sandbox Code Playgroud)

输出看起来像这样: ggplot2输出plot.margin=unit(x=c(0,0,0,0),units="mm")传说上方有一个不寻常的白色(红色)空间.有谁知道如何解决这个问题?

谢谢你的任何提示.

真诚的,约翰

sc_*_*ans 30

就像你说的那样,我不能在你的例子中看到它,但我猜测边缘是传说本身.您可以通过添加来消除图例周围的边距

theme(legend.margin=unit(-0.6,"cm")) # version 0.9.x
Run Code Online (Sandbox Code Playgroud)

你的ggplot图代码.

更新:从版本2.1.0开始,语法已更改,您应该使用

theme(legend.margin=margin(t = 0, unit='cm'))
Run Code Online (Sandbox Code Playgroud)

请注意,至少就目前而言,旧解决方案仍然有效.

在此输入图像描述

  • 面板也有一个边距(“ panel.margin”),将所有设置为零仍会在顶部保留一些额外的空间。如果您坚持要消除它们,则可以将负数作为单位传递,例如:theme(plot.margin = unit(x = c(-5,0,0,0),units =“毫米”) (2认同)
  • 我意识到这不是你问题的确切解决方案,但为什么不把图例放在情节窗口内呢?如果你在绘图窗口的某个地方有很多可用空间,你可以将图例放在那里.使用此示例数据集,`theme(legend.position = c(0.9,0.8))`将图例放在右上角. (2认同)
  • 这改为``theme(legend.margin = margin(t = -0.5,unit ='cm'));`` (2认同)

bap*_*ste 11

如果我夸大边距以获得更多可见性,并运行showViewports,我会得到以下结果:

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)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

从中可以看出,不存在的标题在某种程度上占据了空间.

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

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

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))
Run Code Online (Sandbox Code Playgroud)

所以,确实,这是传说增加一些利润(0.5 + 0.5 =总共1行).我认为它是guide.margin 主题中缺少的选项,正在被半行的默认值替换.

在此输入图像描述


And*_*rew 7

自提出/回答此问题以来的一年中,ggplot进入维护模式,因此将来不会有任何更新(意味着OP的等待更新策略不起作用).

接受的答案依赖于捏造传奇周围的边缘legend.margin.然而,这并不能很好地概括,特别是在使用ggsave()不同尺寸或比例因子时.幸运的是,有一个更通用的通用解决方案.

legend.margin只有一个值用于所有边的填充,而plot.margin顶部,右边,底部和左边距需要四个值.默认边距基于线(而不是mm或英寸),如下所示: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"))
Run Code Online (Sandbox Code Playgroud)

正确的传奇在上面

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

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"))
Run Code Online (Sandbox Code Playgroud)

底部有正确的图例

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