【发布时间】:2019-08-22 18:40:08
【问题描述】:
背景
阅读this beautiful answer on how to extend ggplot 和the corresponding vignette 后,我试图了解如何扩展ggplot。
简而言之
我了解,这些部分是如何组合在一起的,但我错过了一个重要信息:ggplot 如何确定轴的默认范围?
代码
考虑以下玩具示例:
library(grid)
library(ggplot2)
GeomFit <- ggproto("GeomFit", GeomBar,
required_aes = c("x", "y"),
setup_data = .subset2(GeomBar, "setup_data"),
draw_panel = function(self, data, panel_scales, coord, width = NULL) {
bars <- ggproto_parent(GeomBar, self)$draw_panel(data,
panel_scales,
coord)
coords <- coord$transform(data, panel_scales)
tg <- textGrob("test", coords$x, coords$y * 2 - coords$ymin)
grobTree(bars, tg)
}
)
geom_fit <- function(mapping = NULL, data = NULL,
stat = "count", position = "stack",
...,
width = NULL,
binwidth = NULL,
na.rm = FALSE,
show.legend = NA,
inherit.aes = TRUE) {
layer(
data = data,
mapping = mapping,
stat = stat,
geom = GeomFit,
position = position,
show.legend = show.legend,
inherit.aes = inherit.aes,
params = list(
width = width,
na.rm = na.rm,
...
)
)
}
set.seed(1234567)
data_gd <- data.frame(x = letters[1:5],
y = 1:5)
p <- ggplot(data = data_gd, aes(x = x, y = y, fill = x)) +
geom_fit(stat = "identity")
问题
如您所见,某些文本未显示。我假设ggplot 以某种方式计算轴的范围,因为它不知道我的textGrob 所需的额外空间。我该如何解决? (期望的结果相当于p + expand_limits(y = 10)
NB. 当然,我可以将问题推给最终用户,方法是要求添加手动比例。但理想情况下,我希望正确设置秤。
【问题讨论】:
-
ggplot通过乘法和加法扩展数据的范围。用户可以在scale函数的expand参数中设置乘法和加法系数。 See here for an example。当人们想要the plot to not be expanded at all 时,通常会出现这种情况。在最近的版本中,您可以使用expand_scaleto expand the axis in one direction only。?expand_scale是一个不错的起点。 -
我不知道在内部如何确定要扩展的初始轴范围。(这就是为什么我只是评论,而不是回答。)
-
根据我的理解,规模范围是根据数据范围训练的。如果选中
layer_data(p),y 值的范围是 1-5,这就是绘图的比例范围。 -
ggplot如何知道它必须查找哪个范围?使用相同的数据,我可以根据我的映射得到完全不同的范围:d <- data.frame(x = rep(1:10, 10), y = sample(3, 100, TRUE)):p <- ggplot(d, aes(x = x)); p + geom_bar()vsp + geom_bar(aes(y=y), stat = "identity")。所以只有在我们知道我们在geom中使用了哪些映射之后,我们才能确定绘图的范围。 -> 1.哪个函数负责确定范围? 2. 他的函数是从哪个函数调用的? -
@thothal 那将是来自Layout 的
train_position函数。在挖掘 ggplot 对象时,我喜欢使用的一个技巧是在ggplot2:::ggplot_build.ggplot或ggplot2:::ggplot_gtable.ggplot_built(ggplotGrob()的两个阶段)上运行调试,并检查每个步骤中的输出以找到感兴趣的现象(在此案例规模创建)发生。不过要小心,兔子洞会变得非常非常深......