将额外的参数传递给ggplot2中的自定义几何

时间:2019-07-17 08:55:57

标签: r ggplot2

我正在创建一个自定义几何图形,希望它采用一个名为showpoints的附加参数,该参数对实际绘图有其他作用。例如,通过将其设置为FALSE,geom实际上会返回zeroGrob()。我已经找到了一种方法,但是(i)笨拙且有点怪异;(ii)我不完全了解自己在做什么,这是一个不好的信号。问题在于,当您定义新的统计信息时,可以运行setup_params,但是geoms没有它:

  

与统计和位置相比,Geom有所不同,因为   设置和计算功能的执行被拆分。 setup_data   在位置调整之前运行,而draw_layer直到运行   渲染时间,要晚得多。这意味着没有setup_params,因为   很难传达这些更改。

[Source]

基本上,我所拥有的代码在可以使用附加参数来抑制绘制点的意义上起作用:

# draw the points by default
ggplot(mpg, aes(displ, hwy)) + geom_simple_point()

# suppresses drawing of the points
ggplot(mpg, aes(displ, hwy)) + geom_simple_point(showpoints=FALSE)

到目前为止,这是我基于extending ggplot2 tutorial的代码:

## Return the grob to draw. The additional parameter,
## showpoints, determines whether a points grob should be returned,
## or whether zeroGrob() should take care of not showing the points
.draw_panel_func <- function(data, panel_params, coord) {
  coords <- coord$transform(data, panel_params)
  showpoints <- unique(data$showpoints)
  cat("showpoints=", as.character(showpoints), "\n")
  if(!is.null(showpoints) && is.logical(showpoints) && !showpoints) {
    return(zeroGrob())
  } else {
    return(
      grid::pointsGrob(coords$x, coords$y,
        pch = coords$shape,
        gp = grid::gpar(col = coords$colour))
   )
 }
}

## definition of the new geom. setup_data inserts the parameter 
## into data, therefore making it accessible for .draw_panel_func
GeomSimplePoint <- ggproto("GeomSimplePoint", Geom,
  required_aes = c("x", "y"),
  default_aes = aes(shape = 19, colour = "black"),
  draw_key = draw_key_point,
  setup_data = function(data, params) {
    if(!is.null(params$showpoints)) {
      data$showpoints <- params$showpoints
    }
    data
  },
  extra_params = c("na.rm", "showpoints"),
  draw_panel = .draw_panel_func
)

geom_simple_point <- function(mapping = NULL, data = NULL, stat = "identity",
                              position = "identity", na.rm = FALSE, show.legend = NA, 
                              inherit.aes = TRUE, showpoints=TRUE, ...) {
  layer(
    geom = GeomSimplePoint, mapping = mapping,  data = data, stat = stat, 
    position = position, show.legend = show.legend, inherit.aes = inherit.aes,
    params = list(na.rm = na.rm, showpoints=showpoints, ...)
  )
}

是否有一种简单的方法将所选的额外参数传递给geom?如果我可以定义extra_params,为什么不能以某种方式更轻松地访问它们?

1 个答案:

答案 0 :(得分:2)

有一个相对简单的方法,那就是将额外的参数作为参数传递给面板绘制函数。这是一个适用于您的geom_simple_point()的简单示例:

GeomSimplePoint <- ggproto(
  "GeomSimplePoint", 
  GeomPoint,
  extra_params = c("na.rm", "showpoints"),
  draw_panel = function(data, panel_params, 
                        coord, na.rm = FALSE, showpoints = TRUE) {
    if (showpoints) {
      return(GeomPoint$draw_panel(data, panel_params, coord, na.rm = na.rm))
    } else {
      return(zeroGrob())
    }
  }
)

顺便说一句,如果您想复制已经存在的geom的行为,例如geom_point(),则更容易设置自己的ggproto对象以从该geom的ggproto对象继承。这样,您在ggproto中指定的默认aes,必需aes和其他参数会自动从该geom复制/继承,而您不必手动指定所有这些参数。