如何编写一个ggplot'+' - 可管理的函数,可以参考输入图

Rus*_*yde 5 r ggplot2 ggproto

我正在尝试编写一个可以使用基于'+'的ggplot2语法调用的函数.

myplot + myfunction

具体来说,我正在编写的函数将y轴对称为零,因此需要确定输入图的y轴范围.

所以让,

ylim_sym <- function(p){
    get_y_range <- function(p){
        ggplot2::ggplot_build(p)$layout$panel_ranges[[1]]$y.range
        }
    max_offset <- max(abs(get_y_range(p)))
    p + ylim(- max_offset, max_offset)
}
Run Code Online (Sandbox Code Playgroud)

使用此功能,以下工作:

qplot(x = 1:10, y = exp(rnorm(10))) %>% ylim_sym()
Run Code Online (Sandbox Code Playgroud)

但是,这并不因为之间的一些优先发布合作+.gg%>%:

qplot(x = 1:10, y = exp(rnorm(10))) +
    geom_abline(slope = 0) %>%
    ylim_sym()
Run Code Online (Sandbox Code Playgroud)

(我可以写后者,(all_my_ggplot_pipeline) %>% ylim_sym()但这是非常难看的语法).

理想情况下,我希望能够写出ylim_sym这样的内容,就像这样,

qplot(x = 1:10, y = exp(rnorm(10))) + ylim_sym()
Run Code Online (Sandbox Code Playgroud)

但我无法弄清楚如何访问+内部LHS的情节ylim_sym

有任何想法吗?

Rus*_*yde 5

我能够通过以下方式解决它.

StatSymYLim <- ggproto(
  "StatSymYLim", Stat, 
  compute_group = function(data, scales) {
    out <- data.frame(
      x = median(data$x),
      y = c(-1, 1) * max(abs(data$y))
      )
    out
    },
    required_aes = c("x", "y")
  )

ylim_sym <- function(...){
  geom_blank(..., stat = StatSymYLim)
  }
Run Code Online (Sandbox Code Playgroud)

然后根据需要执行以下操作:

qplot(x = 1:10, y = exp(rnorm(10))) +
  geom_abline(slope = 0) +
  ylim_sym()
Run Code Online (Sandbox Code Playgroud)

我对ggplot2内部的理解非常不公平,所以这可能是一个天真的解决方案.