R语言 从ggplot对象检测变换的应用顺序

vngu2lb8  于 2023-04-09  发布在  其他
关注(0)|答案(1)|浏览(85)

这些对象打印相同,但对象本身不同。

library(ggplot2)
p1 <- ggplot(cars, aes(speed, dist)) + xlim(1, 2) + geom_point() + geom_line()
p2 <- ggplot(cars, aes(speed, dist)) + geom_point() + xlim(1, 2) + geom_line()
p3 <- ggplot(cars, aes(speed, dist)) + geom_point() + geom_line() + xlim(1, 2)
length(waldo::compare(p1, p2))
#> [1] 229
length(waldo::compare(p1, p3))
#> [1] 190

我想从一个ggplot对象本身来理解应用转换的顺序。
我们可以使用p1$layersp1$scales等访问层,尺度等,我们可以按照设备的顺序 * 通过转换类型 * 在那里找到它们,但我需要知道整体顺序。
我相信每个转换对象都以某种方式跟踪前一个对象,因此我们应该能够从所有对象中遍历树并从那里获得图片,但我不确定如何做到这一点。
一般的答案是最好的,但一个答案,将工作“90%的时间”也将不胜感激。一般的问题不仅是关于规模和层,但也应该包括其他转换以及(坐标,位置,主题),只要他们的位置相对于其他类型的对象改变输出。
给定示例的输出可能如下所示:

# 1st scale than 1st layer then 2nd layer
gg_order(p1)
#> scales layers layers 
#>      1      1      2

# 1st layer than 1st scale then 2nd layer
gg_order(p2)
#> layers scales layers 
#>      1      1      2

# 1st layer than 2nd layer then 1st scale
gg_order(p3)
#> layers layers scales 
#>      1      2      1

转换的数量不必与原始代码中的函数数量相匹配,因为一些函数应用几个转换。
编辑:
我设计了一些工具来帮助导航waldo diffs,这可能会有所帮助:

devtools::install_github("moodymudskipper/woof")
woof::woof_compare(p1, p2)
w <- woof::woof_compare(p1, p2)
w$scales$super$..env$env$self$super$..env
print(w$scales$super$..env$env$self$super$..env, substitute = TRUE)
wooyq4lh

wooyq4lh1#

这不是一个答案,因为这将帮助你进一步实现你的目标,但也许它可以帮助你确定一个不同的目标。
Waldo报告这些图之间的差异的原因是,在添加每一层时,比例都是克隆的:新的刻度成为旧刻度的子环境。因此,plot对象的“状态”应该取决于在xlim()函数之后添加了多少对象,因为此操作克隆了该函数产生的刻度。克隆发生在这行源代码中:
https://github.com/tidyverse/ggplot2/blob/d7f22413efea3dd2a7c9effff05d4b2aa2c2d300/R/plot.R#L150
我相信这种规模的克隆是什么让沃尔多报告的差异,但我不认为克隆是能够跟踪任何国家在其他部分的情节,因此您的目标可能无法实现。
我之所以这么认为,是因为可以做以下练习。如果你fork ggplot 2,然后注解掉特定的一行,这些plot对象变得相同(但不会正确渲染):

library(ggplot2) # 3.4.2 from CRAN

p1 <- ggplot(cars, aes(speed, dist)) + xlim(1, 2) + geom_point() + geom_line()
p2 <- ggplot(cars, aes(speed, dist)) + geom_point() + xlim(1, 2) + geom_line()
p3 <- ggplot(cars, aes(speed, dist)) + geom_point() + geom_line() + xlim(1, 2)

length(waldo::compare(p1, p2))
#> [1] 224
length(waldo::compare(p1, p3))
#> [1] 190

# Now with local fork with that line commented out
# Path may differ on your machine
devtools::load_all("~/packages/ggplot2/")
#> ℹ Loading ggplot2

p1 <- ggplot(cars, aes(speed, dist)) + xlim(1, 2) + geom_point() + geom_line()
p2 <- ggplot(cars, aes(speed, dist)) + geom_point() + xlim(1, 2) + geom_line()
p3 <- ggplot(cars, aes(speed, dist)) + geom_point() + geom_line() + xlim(1, 2)

waldo::compare(p1, p2)
#> ✔ No differences
waldo::compare(p1, p3)
#> ✔ No differences

创建于2023-04-08使用reprex v2.0.2
因此,除非一个人真的是一个R向导,并且能够从这些缩放环境中找出不同的状态,否则我认为操作的顺序是无法单独从情节对象中恢复的。
我很高兴被证明是错的!

相关问题