ggplot2如何强制y轴从原点开始并浮动y轴上限?

10

经过一番搜索,我仍然不满意!

有没有一种简单的方法可以制作一个以原点为起点并清晰显示所有数据的y轴图表呢?

这是我的问题:

set.seed(123)
my.data<- data.frame(x.var = rnorm(100, 50),
                     y.var = rnorm(100, 50,10))


## Annoying because it doesn't start at origin
ggplot(my.data, aes(x.var, y.var))+
  geom_point()


## Annoying because origin is not at bottom
ggplot(my.data, aes(x.var, y.var))+
  geom_point()+
  expand_limits(y = 0)

## Annoying because point is cut off
ggplot(my.data, aes(x.var, y.var))+
  geom_point()+
  scale_y_continuous(expand = c(0,0))+
  expand_limits(y = 0)

问题“如何在ggplot2(R)中强制原点从0开始”中的最佳答案最后以以下内容结束:
“您可能需要稍微调整一下,以确保点不会被截断。”
为什么会发生这种情况?我可以手动调整轴,但我不想每次都这样做!
互联网上的某个人有一个解决方案,其中涉及…
#Find the current ymax value for upper bound
#(via https://dev59.com/nmsz5IYBdhLWcg3wuKQm#GaWeEYcBWogLw_1btlCn )
gy=ggplot_build(g)$panel$ranges[[1]]$y.range[2]
g=g+ylim(0,gy)

#Handle the overflow by expanding the x-axis
g=g+scale_x_continuous(expand=c(0.1,0))

对于我觉得相对简单的想法来说,这似乎很复杂。我有什么遗漏的吗?

谢谢!


编辑:截至2018年夏季,ggplot更新使上述修复方法不再适用。目前(2018年8月),要从图中获取y-max,您现在需要执行以下操作。

gy = ggplot_build(g)$layout$panel_scales_y[[1]]$range$range[[2]]


1
或者使用@joran的ylimits,使用ggplot(my.data,aes(x.var,y.var))+ geom_point()+ coord_cartesian(ylim = c(0,1.05 * max(my.data $ y.var))) - rawr
https://dev59.com/Zmgu5IYBdhLWcg3wloG_这个回答解决了你的问题吗?还是说你需要y轴底部完全为0,没有任何填充(而y轴顶部仍然有正常的填充)? - Brian Diggs
1
@BrianDiggs 我希望底部没有填充,顶部有正常的填充。也许我想要将y=0作为图形底部的愿望应该重新评估。这似乎是如何最好地显示信息的问题。 - Michael
@Michael 不填充:对我来说这似乎是一个非常合理的要求... - PatrickT
“scale_x_continuous” 中的 “limits” 选项似乎会移除填充,如果我理解的话。 - PatrickT
2个回答

14

我发现这个问题很令人沮丧,然后阅读了R帮助文件中的expansion()。有一个很好的ggplot选项,适合分面、动态和简洁。

引用帮助文件:

mult
倍增量的向量。如果长度为1,则比例尺的下限和上限都将扩展mult倍。如果长度为2,则下限将扩展mult [1],上限将扩展mult [2]。

请注意,add也是具有类似结构的选项。我会这样解决这个问题:

ggplot(my.data, aes(x.var, y.var))+
  geom_point()+
  scale_y_continuous(limits = c(0, NA),
                     expand = expansion(mult = c(0, 0.1)))
偏爱这种方法的一个重要原因是,如果您有不同美学的几何对象(例如点和误差线)以及自由比例尺的图层... 您仍然可以利用ggplot的聪明默认y轴行为,但强制x在每个面板上与y相交于0,并且仍然可以看到最上面的数据点。

2

为什么不直接这样做:

ggplot(my.data, aes(x.var, y.var))+
    geom_point()+
    scale_y_continuous(expand = c(0,0))+
    expand_limits(y = c(0,1.05 * max(my.data$y.var)))

我想这样做可能可行,尽管它仍需要针对每个变量和数据集使用不同的修复方法。 - Michael
@Michael 如果您想要自定义轴限制而不是自动计算,那么您应该自己计算。对于每个数据集。在我的代码中,如果我有挑剔的轴要求,我会编写一些代码,使用所有用作输入的数据框来计算所需的范围。 - joran
1
这肯定是“更多的工作”!你可能会说它与为x和y设置美学并没有太大的区别,但它毕竟是另一步。 - Michael
@Michael,我记得我们曾经讨论过在设置坐标轴限制时使用Inf的情况。我记不清是否实际执行了。我现在离开了电脑,无法测试。你可以尝试一下使用Inf和NA... - joran
1
使用 ylim(0,NA) 可以处理上限,但会将 y=0 放在图形底部的上方。对我来说,这似乎不是理想的选择,因为你的眼睛会将点下面的空间视觉化为该值的大小。也许我应该忘记它... - Michael
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接