ggplot对象修改时如何添加警告?

How to add a warning when ggplot object is modified?

提问人:Jeff 提问时间:4/12/2023 更新时间:4/12/2023 访问量:46

问:

我有一个修改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)

但是,该功能在IRL上所做的一些修补是非常脆弱的。我怎样才能设置一个闹钟,如果有人试图添加一个喜欢:pnewscale_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.
r ggplot2 警告

评论


答:

2赞 tjebo 4/12/2023 #1

我认为一种选择是更改返回对象的类。这也需要您创建自己的打印方法。我在这里只是复制print.ggplot方法,以及快速破解的必要功能。

现在(在我的预期中)应该不能再添加另一个 ggplot 层了。但是,在尝试此操作时,添加某些层不会产生错误或警告,而只是“NULL”。但也许这已经是一个开始。

缺少警告/错误可能是由于 ggplot 方法的双重调度。因此,解决该问题的一个解决方案可能是创建自己的方法,就像 {GGally} 或 {patchwork} 包一样。但这是有代价的:例如,GGally 方法对 ggplot2 自己的方法有一些相当讨厌的干扰(或者至少:曾经有过),我认为拼凑包有一些非常聪明的方法来避免这种干扰,这可能超出了这个答案的范围——但如果你想走这条路,也许值得一看他们的源代码。+.gg+.gg

这是一个讨论自定义方法创建的 SO 线程。S3 方法:扩展 ggplot2 '+.gg' 函数+.gg

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-04-12 with reprex v2.0.2

评论

0赞 tjebo 4/12/2023
(可能与 GitHub 线程 github.com/tidyverse/ggplot2/pull/3818 相关)