... le plaisir n'est pas une esthétique ... vous pouvez en faire un :)
C'est un peu exagéré, mais c'est juste une démonstration rapide de ce qui est possible en modifiant les Geoms et les Stats. Ce qui suit est un hack rapide et je l'ai référencé avec pas mal de choses moches. :::
ce que vous ne feriez pas si vous emballiez correctement ce produit. En outre, il est clair que ce n'est pas correctement testé sur de nombreux cas d'utilisation. Quelques commentaires supplémentaires dans le code.
C'était assez ... amusant :)
df <- data.frame(x = 0, fun = c("sin", "cos", "tan", "mean"))
ggplot(df, aes(x)) +
stat_function2(aes(fun = fun)) +
xlim(c(-5,5)) +
facet_wrap(~fun, scales = "free_y")
Modifier Geom et Stat - StatFunction2
StatFunction2 <- ggplot2:::StatFunction
## removing fun from the arguments
StatFunction2$compute_group <- function (data, scales, xlim = NULL, n = 101, args = list())
{
if (is.null(scales$x)) {
## need to change that here a bit
range <- rlang::`%||%`(xlim, c(0, 1))
xseq <- seq(range[1], range[2], length.out = n)
x_trans <- xseq
}
else {
## same same
range <- rlang::`%||%`(xlim, scales$x$dimension())
xseq <- seq(range[1], range[2], length.out = n)
if (scales$x$is_discrete()) {
x_trans <- xseq
}
else {
x_trans <- scales$x$trans$inverse(xseq)
}
}
## get the function, this is the trick :)
fun <- unique(data$fun)
if (plyr::is.formula(fun))
fun <- as_function(fun)
y_out <- do.call(fun, c(list(quote(x_trans)), args))
if (!is.null(scales$y) && !scales$y$is_discrete()) {
y_out <- scales$y$trans$transform(y_out)
}
ggplot2:::new_data_frame(list(x = xseq, y = y_out))
}
## update stat_function - remove fun argument and reference new geom_function2
stat_function2 <- function (mapping = NULL, data = NULL, geom = "function2", position = "identity",
..., fun, xlim = NULL, n = 101, args = list(), na.rm = FALSE,
show.legend = NA, inherit.aes = TRUE)
{
if (is.null(data)) {
### those ::: are just for to make it work here
data <- ggplot2:::ensure_nonempty_data
}
layer(data = data, mapping = mapping, stat = StatFunction2,
geom = geom, position = position, show.legend = show.legend,
## fun needs to be removed here too.
inherit.aes = inherit.aes, params = list(n = n,
args = args, na.rm = na.rm, xlim = xlim, ...))
}
## This is the correct way to create copies (children) of ggproto objects
## see https://stackoverflow.com/a/70637511/7941188
GeomFunction2 <- ggproto(NULL, GeomFunction)
## change the required aesthetics - this removes the warning that aesthetics are not known
GeomFunction2$required_aes <- c("x", "y", "fun")
## update the corresponding geom (two locations in this function definition)
geom_function2 <- function (mapping = NULL, data = NULL, stat = "function2", position = "identity",
..., na.rm = FALSE, show.legend = NA, inherit.aes = TRUE)
{
if (is.null(data)) {
data <- ensure_nonempty_data
}
layer(data = data, mapping = mapping, stat = stat, geom = GeomFunction2,
position = position, show.legend = show.legend, inherit.aes = inherit.aes,
params = list(na.rm = na.rm, ...))
}