我有一个修改 ggplot 对象的函数:
p = ggplot(mtcars, aes(x=cyl, y=mpg)) + geom_point()
mod_gg <- function(plot) {
plot$labels$x = "CYL"
return(plot)
}
pnew = mod_gg(p)
但是,该函数在现实生活中所做的一些修改非常脆弱。我如何在 pnew
中设置警报,以便如果有人尝试添加 scale_x_*
,例如:
> pnew = pnew + scale_x_discrete(limits = c(5,7)) # This shouldn't happen
弹出错误、警告或消息来警告用户不要执行该操作。这可能就像您尝试将两个scale_x_* 添加到单个绘图中一样:
# Example
> pnew + scale_x_discrete(limits = c(5,7)) + scale_x_discrete(limits = c(5,7))
Scale for x is already present.
Adding another scale for x, which will replace the existing scale.
最佳答案
我认为一种选择是更改返回对象的类。这将要求您也创建自己的打印方法。我在这里只是简单地复制 print.ggplot 方法以及它的必要函数。
现在(按照我的预期)应该不可能再添加另一个 ggplot 层了。但是,在尝试此操作时,添加一些层不会产生错误或警告,而只是产生“NULL”。但也许这已经是一个开始了。
缺少警告/错误可能是由于 ggplot 的 +.gg
方法的双重调度造成的。因此,解决该问题的一种方法可能是创建您自己的 +.gg
方法,就像 {GGally} 或 {patchwork} 包所做的那样。但这是有代价的:例如,GGally 方法对 ggplot2 自己的方法有(或者至少:曾经有)一些相当讨厌的干扰,并且我认为 patchwork 包有一些非常聪明的方法来避免这种干扰,这将可能超出了这个答案的范围 - 但如果你想走这条路,也许值得看看他们的源代码。
这里是一个 SO 线程,讨论自定义 +.gg
方法的创建。 S3 Methods: Extending ggplot2 `+.gg` function
library(ggplot2)
p <- ggplot(mtcars, aes(x = cyl, y = mpg)) +
geom_point()
## this is just a quick hack for reprex purpose
## would need some more in detail work when building your package
print.myplot <- ggplot2:::print.ggplot
ggplot_build.myplot <- ggplot2:::ggplot_build.ggplot
get_alt_text.myplot <- ggplot2:::get_alt_text.ggplot
mod_gg <- function(plot) {
plot$labels$x <- "CYL"
class(plot) <- "myplot"
plot
}
pnew <- mod_gg(p)
## The object can be printed with your new printing method
pnew
## but other ggplot layers should (in theory) not be addable.
pnew + scale_x_continuous(limits = c(5, 7))
#> NULL
pnew + geom_smooth()
#> NULL
pnew + labs()
#> Error in pnew + labs(): non-numeric argument to binary operator
创建于 2023 年 4 月 12 日 reprex v2.0.2
关于r - 如何在ggplot对象被修改时添加警告?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75992108/