【问题标题】:How to write a ggplot '+'-pipeable function that can refer to the input plot如何编写可以引用输入图的 ggplot '+'-pipeable 函数
【发布时间】:2017-12-13 17:13:23
【问题描述】:

我正在尝试编写一个可以使用基于 '+' 的 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)
}

使用此功能,以下工作:

qplot(x = 1:10, y = exp(rnorm(10))) %>% ylim_sym()

但这不起作用,因为+.gg%&gt;% 之间存在一些优先级问题:

qplot(x = 1:10, y = exp(rnorm(10))) +
    geom_abline(slope = 0) %>%
    ylim_sym()

(我可以写后者(all_my_ggplot_pipeline) %&gt;% ylim_sym(),但它的语法很丑)。

理想情况下,我希望能够编写 ylim_sym 以便可以像这样通过管道传输,

qplot(x = 1:10, y = exp(rnorm(10))) + ylim_sym()

但我不知道如何在ylim_sym 内访问+ LHS 上的图

有什么想法吗?

【问题讨论】:

  • 抱歉,ggplot 出现在管道之前。 %&gt;% 运算符与 + 运算符非常非常不同。您不能将行为包装在您的函数中。最好只是把它吸起来并使用括号:(a+b) %&gt;% c
  • 同意。或ylim_sym &lt;- function(y) { ylim(-max(abs(y)), max(abs(y))) } 至少为了方便起见。

标签: r ggplot2 ggproto


【解决方案1】:

我能够通过执行以下操作来解决它。

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)
  }

然后根据需要进行以下工作:

qplot(x = 1:10, y = exp(rnorm(10))) +
  geom_abline(slope = 0) +
  ylim_sym()

公平地说,我对 ggplot2 内部结构的理解非常不稳定,所以这可能是一个幼稚的解决方案。

【讨论】:

  • 这是一个很好的解决方案!当您提出一个好问题时,欢迎您accept您自己的答案,因为它可能对其他人有所帮助。
  • 谢谢,在有人告诉你不可能之后,你总能找到解决方案......
【解决方案2】:

注意:您的函数需要更新,因为对象的结构略有变化

使用package ggfun 这会起作用:

# devtools::install_github("moodymudskipper/ggfun")
library(ggfun)

ylim_sym <- function(p){
  get_y_range <- function(p){
    ggplot2::ggplot_build(p)$layout$panel_params[[1]]$y.range
  }
  max_offset <- max(abs(get_y_range(p)))
  p + ylim(- max_offset, max_offset)
}

qplot(x = 1:10, y = exp(rnorm(10))) +
  geom_abline(slope = 0) +
  ylim_sym

【讨论】:

  • 谢谢。收到更新说明时,您使用的是哪个版本的 ggplot2?
  • 我没有收到任何通知,我只是无法让您的功能正常工作,因此我探索了该对象 :)。我使用 ggplot 3.0.0,我现在看到它不是最后一个,所以我希望这仍然有效,不过它是在您提出问题后发布的。您在完成这项工作时遇到问题吗?
  • 啊,对不起。我认为斜体是 ggplot 生成的警告/注释。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-19
  • 1970-01-01
  • 1970-01-01
  • 2015-09-11
  • 1970-01-01
  • 2012-06-08
相关资源
最近更新 更多