如何跨几何对齐比例转换?
How to align scale transformation across geoms?
我有一个 geom_foo()
,它将对输入数据进行一些转换,并且我有一个比例转换。我的问题是,这些在缩放方面并不像我预期的那样与其他 geom_*
一起工作。
为了说明该行为,请考虑 foo()
,它将在问题末尾定义的 GeomFoo
的 setup_data
方法中使用。
foo <- function(x, y) {
data.frame(
x = x + 2,
y = y + 2
)
}
foo(1, 1)
变压器是:
foo_trans <- scales::trans_new(
name = "foo",
transform = function(x) x / 5,
inverse = function(x) x * 5
)
鉴于此输入数据:
df1 <- data.frame(x = c(1, 2), y = c(1, 2))
这是一个基本情节:
library(ggplot2)
ggplot(df1, aes(x = x, y = y)) +
geom_foo()
当我将转换应用于垂直比例时,我得到了这个
ggplot(df1, aes(x = x, y = y)) +
geom_foo() +
scale_y_continuous(trans = foo_trans)
我能说的是,y 轴限制计算为 11 = 1 + (2*5)
和 12 = 2 + (2*5)
,其中 1
和 2
是 df1$y
,和 (2 * 5)
取自 setup_data
方法和 trans_foo
.
我真正的问题是,我想添加一个带有标签的文本层。这些标签及其坐标来自另一个数据框,如下所示。
df_label <- foo(df1$x, df1$y)
df_label$label <- c("A", "B")
标签层和点层在相同的 x-y 位置上,没有进行比例变换
p <- ggplot(df1, aes(x = x, y = y)) +
geom_foo(color = "red", size = 6) +
geom_text(data = df_label, aes(x, y, label = label))
p
但是当我应用变换时,坐标不再匹配
p +
scale_y_continuous(trans = foo_trans)
如何在转换后使图层在 x-y 坐标中匹配?谢谢
ggproto
对象:
GeomFoo <- ggproto("GeomFoo", GeomPoint,
setup_data = function(data, params) {
cols_to_keep <- setdiff(names(data), c("x", "y"))
cbind(
foo(data$x, data$y),
data[, cols_to_keep]
)
}
)
geom
构造函数:
geom_foo <- function(mapping = NULL, data = NULL, ...,
na.rm = FALSE, show.legend = NA,
inherit.aes = TRUE) {
layer(
data = data,
mapping = mapping,
stat = "identity",
geom = GeomFoo,
position = "identity",
show.legend = show.legend,
inherit.aes = inherit.aes,
params = list(
na.rm = na.rm,
...
)
)
}
进行数据转换并不是 geom 的真正任务,而是 stat 的任务。也就是说,更大的问题是在调用 GeomFoo$setup_data()
方法之前应用了比例转换。我可以看到有两种方法可以完成这项任务。
在缩放转换之前应用foo()
。我认为 geoms 或 stats 在 before scale transformation 之前无法访问数据。一个可能的地方是在 ggplot2:::Layer$setup_layer()
方法中。然而,这并没有导出,这可能意味着开发人员甚至在我们尝试之前就想阻止它。
逆比例变换,应用foo()
,再次变换。为此,您需要一种可以访问秤的方法。 AFAIK,没有 geom 方法具有此访问权限。但是 Stat$compute_panel()
可以访问,所以我们可以使用它。
举一个 (2) 的例子,我认为你可以逃避以下问题:
StatFoo <- ggproto(
"StatFoo", Stat,
compute_panel = function(self, data, scales) {
cols_to_keep <- setdiff(names(data), c("x", "y"))
food <- foo(scales$x$trans$inverse(data$x),
scales$y$trans$inverse(data$y))
cbind(
data.frame(x = scales$x$trans$transform(food$x),
y = scales$y$trans$transform(food$y)),
data[, cols_to_keep]
)
}
)
geom_foo <- function(mapping = NULL, data = NULL, ...,
na.rm = FALSE, show.legend = NA,
inherit.aes = TRUE) {
layer(
data = data,
mapping = mapping,
stat = StatFoo,
geom = GeomPoint,
position = "identity",
show.legend = show.legend,
inherit.aes = inherit.aes,
params = list(
na.rm = na.rm,
...
)
)
}
如果其他人对此有更好的想法,我也很想知道!
我有一个 geom_foo()
,它将对输入数据进行一些转换,并且我有一个比例转换。我的问题是,这些在缩放方面并不像我预期的那样与其他 geom_*
一起工作。
为了说明该行为,请考虑 foo()
,它将在问题末尾定义的 GeomFoo
的 setup_data
方法中使用。
foo <- function(x, y) {
data.frame(
x = x + 2,
y = y + 2
)
}
foo(1, 1)
变压器是:
foo_trans <- scales::trans_new(
name = "foo",
transform = function(x) x / 5,
inverse = function(x) x * 5
)
鉴于此输入数据:
df1 <- data.frame(x = c(1, 2), y = c(1, 2))
这是一个基本情节:
library(ggplot2)
ggplot(df1, aes(x = x, y = y)) +
geom_foo()
当我将转换应用于垂直比例时,我得到了这个
ggplot(df1, aes(x = x, y = y)) +
geom_foo() +
scale_y_continuous(trans = foo_trans)
我能说的是,y 轴限制计算为 11 = 1 + (2*5)
和 12 = 2 + (2*5)
,其中 1
和 2
是 df1$y
,和 (2 * 5)
取自 setup_data
方法和 trans_foo
.
我真正的问题是,我想添加一个带有标签的文本层。这些标签及其坐标来自另一个数据框,如下所示。
df_label <- foo(df1$x, df1$y)
df_label$label <- c("A", "B")
标签层和点层在相同的 x-y 位置上,没有进行比例变换
p <- ggplot(df1, aes(x = x, y = y)) +
geom_foo(color = "red", size = 6) +
geom_text(data = df_label, aes(x, y, label = label))
p
但是当我应用变换时,坐标不再匹配
p +
scale_y_continuous(trans = foo_trans)
如何在转换后使图层在 x-y 坐标中匹配?谢谢
ggproto
对象:
GeomFoo <- ggproto("GeomFoo", GeomPoint,
setup_data = function(data, params) {
cols_to_keep <- setdiff(names(data), c("x", "y"))
cbind(
foo(data$x, data$y),
data[, cols_to_keep]
)
}
)
geom
构造函数:
geom_foo <- function(mapping = NULL, data = NULL, ...,
na.rm = FALSE, show.legend = NA,
inherit.aes = TRUE) {
layer(
data = data,
mapping = mapping,
stat = "identity",
geom = GeomFoo,
position = "identity",
show.legend = show.legend,
inherit.aes = inherit.aes,
params = list(
na.rm = na.rm,
...
)
)
}
进行数据转换并不是 geom 的真正任务,而是 stat 的任务。也就是说,更大的问题是在调用 GeomFoo$setup_data()
方法之前应用了比例转换。我可以看到有两种方法可以完成这项任务。
在缩放转换之前应用
foo()
。我认为 geoms 或 stats 在 before scale transformation 之前无法访问数据。一个可能的地方是在ggplot2:::Layer$setup_layer()
方法中。然而,这并没有导出,这可能意味着开发人员甚至在我们尝试之前就想阻止它。逆比例变换,应用
foo()
,再次变换。为此,您需要一种可以访问秤的方法。 AFAIK,没有 geom 方法具有此访问权限。但是Stat$compute_panel()
可以访问,所以我们可以使用它。
举一个 (2) 的例子,我认为你可以逃避以下问题:
StatFoo <- ggproto(
"StatFoo", Stat,
compute_panel = function(self, data, scales) {
cols_to_keep <- setdiff(names(data), c("x", "y"))
food <- foo(scales$x$trans$inverse(data$x),
scales$y$trans$inverse(data$y))
cbind(
data.frame(x = scales$x$trans$transform(food$x),
y = scales$y$trans$transform(food$y)),
data[, cols_to_keep]
)
}
)
geom_foo <- function(mapping = NULL, data = NULL, ...,
na.rm = FALSE, show.legend = NA,
inherit.aes = TRUE) {
layer(
data = data,
mapping = mapping,
stat = StatFoo,
geom = GeomPoint,
position = "identity",
show.legend = show.legend,
inherit.aes = inherit.aes,
params = list(
na.rm = na.rm,
...
)
)
}
如果其他人对此有更好的想法,我也很想知道!