R,ggplot2:如何在ggplot2中可视化图形对象的数据、属性和其他组件的继承或流



我经常不确定ggplot2中图形对象的数据、属性和其他组件的哪些元素是由哪些其他元素继承的,以及流到默认值(例如geoms(的来源。在特定情况下,这些问题通常可以通过仔细阅读哈德利的ggplot2书来回答。但我会发现在ggplot2中对继承的整体流程进行某种可视化是很有用的,我想知道是否有人见过、创建过或知道如何创建这样的东西。同样,在一个级别的规范(如aes或主题(中出现并由另一个级别(如geom或scale(继承的默认值的紧凑列表对我来说非常有用,我怀疑对许多学习如何使用ggplot2的人来说也是如此。

我会接受以下任何一个答案:

  1. 继承可视化(可能是网络?(或指针相同
  2. 用于构造继承可视化的代码,或指向同样
  3. 一种替代的、非视觉的方法,使其变得简单,或者至少更容易理解和记住这样的传承和答案具体问题
  4. 参数默认值的列表,显示它们出现的位置以及哪些子函数继承了它们,或者生成这样的列表

这个问题似乎同时涉及ggplot包的多个级别,但我会尽力提供一些信息。几乎不可能在一个堆栈溢出答案中描述ggplot的整个继承系统,但指出正确的函数可能有助于您入门。

在顶层,数据和美学映射都继承自主ggplot调用。在下面的代码中,geom_point()继承映射和数据:

ggplot(iris, aes(Sepal.Width, Sepal.Length)) +
geom_point()

除非您明确提供一个替代映射并将继承设置为false:

ggplot(iris, aes(Sepal.Width, Sepal.Length)) +
geom_point(aes(Petal.Width, Petal.Length), inherit.aes = FALSE)

接下来,在各个层的级别上,从统计、地理或位置继承某些默认值。考虑以下图表:

df <- reshape2::melt(volcano)
ggplot(df, aes(Var1, Var2)) +
geom_raster()

光栅将是深灰色,因为我们还没有指定填充贴图。您可以通过查看他们的ggproto对象来了解geom/stat的默认值:

> GeomRaster$default_aes
Aesthetic mapping: 
* `fill`  -> "grey20"
* `alpha` -> NA
> StatDensity$default_aes
Aesthetic mapping: 
* `y`    -> `stat(density)`
* `fill` -> NA

了解层如何给定其参数的另一个关键因素是查看layer()代码。具体来说,这里的这个比特(为了清晰起见缩写(:

function (geom = NULL, stat = NULL, data = NULL, mapping = NULL, 
position = NULL, params = list(), inherit.aes = TRUE, check.aes = TRUE, 
check.param = TRUE, show.legend = NA, key_glyph = NULL, 
layer_class = Layer) 
{
...
aes_params <- params[intersect(names(params), geom$aesthetics())]
geom_params <- params[intersect(names(params), geom$parameters(TRUE))]
stat_params <- params[intersect(names(params), stat$parameters(TRUE))]
...
ggproto("LayerInstance", layer_class, geom = geom, geom_params = geom_params, 
stat = stat, stat_params = stat_params, data = data, 
mapping = mapping, aes_params = aes_params, position = position, 
inherit.aes = inherit.aes, show.legend = show.legend)
}

其中,您可以看到,无论您给出什么参数,都会根据stat/geom/position的有效参数进行检查,并将其分布到层的适当部分。从上一次调用中可以看到,创建了一个Layer ggproto对象。该类的父级不会导出,但您仍然可以检查该对象内的函数。例如,如果你想知道美学是如何评价的,你可以键入:

ggplot2:::Layer$compute_aesthetics

你可以看到,这里也包含了一些天平的默认值。当然,如果你不了解调用这些层函数的操作顺序,那么这些层做什么就没有多大意义了。为此,我们可以查看绘图生成器(为了清晰起见,也缩写为(:

> ggplot2:::ggplot_build.ggplot
function (plot) 
{
...
data <- by_layer(function(l, d) l$setup_layer(d, plot))
...
data <- by_layer(function(l, d) l$compute_aesthetics(d, plot))
data <- lapply(data, scales_transform_df, scales = scales)
...
data <- layout$map_position(data)
data <- by_layer(function(l, d) l$compute_statistic(d, layout))
data <- by_layer(function(l, d) l$map_statistic(d, plot))
scales_add_missing(plot, c("x", "y"), plot$plot_env)
data <- by_layer(function(l, d) l$compute_geom_1(d))
data <- by_layer(function(l, d) l$compute_position(d, layout))
...
data <- by_layer(function(l, d) l$compute_geom_2(d))
data <- by_layer(function(l, d) l$finish_statistics(d))
...
structure(list(data = data, layout = layout, plot = plot), 
class = "ggplot_built")
}

由此,您可以看到,首先设置图层,然后计算美学,然后应用比例变换,然后计算统计数据,然后计算geom的一部分,然后计算位置,最后重置geom。

这意味着,你所输入的统计变换将受到尺度变换的影响,但不会受到坐标变换的影响(稍后将在其他地方介绍(。

如果你仔细阅读代码,你会发现到目前为止,几乎没有任何主题相关的评估(除了一些使用facets的主题评估(。正如您所看到的,building函数返回类ggplot_build的对象,该对象仍然不是图形输出。主题元素的解释和地理对网格图形的实际解释发生在以下功能中:

ggplot2:::ggplot_gtable.ggplot_built

在这个函数之后,您将有一个可以由grid::grid.draw()解释的gtable对象,它将输出到您的图形设备。

不幸的是,我不太熟悉主题元素的继承,但正如JonSpring在评论中指出的那样,一个好的起点是文档。希望我已经指出了函数在ggplot中查找继承模式的位置。

最新更新