Передача дополнительного параметра настраиваемому geom в ggplot2

Я создаю настраиваемую геометрию и хотел бы, чтобы она принимала дополнительный параметр, называемый showpoints, который что-то делает с фактическим сюжетом. Например, если установить значение FALSE, geom фактически вернет zeroGrob(). Я нашел способ сделать это, но (1) это неуклюже и несколько странно, и (2) я не совсем понимаю, что делаю, что является плохим знаком. Проблема в том, что когда вы определяете новый стат, можно запустить setup_params, но у geom его нет:

По сравнению со Stat и Position, Geom немного отличается, потому что выполнение функций настройки и вычислений разделено. setup_data запускается до корректировки положения, а draw_layer не запускается до времени рендеринга, намного позже. Это означает, что нет setup_params, потому что об изменениях сложно сообщить.

[Источник]

По сути, код, который у меня есть, работает в том смысле, что вы можете использовать дополнительный параметр для подавления рисования точек:

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

Вот мой код, основанный на руководстве по расширению ggplot2:

## 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, ...)
  )
}

Есть ли более простой способ просто передать выбранный дополнительный параметр геометрии? Если я могу определить extra_params, почему я не могу получить к ним доступ как-то более легко?


person January    schedule 17.07.2019    source источник


Ответы (1)


Существует относительно простой способ - передать дополнительный параметр в качестве аргумента функции рисования панели. Вот простой пример, который будет работать с вашим 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 для наследования от объекта ggproto этого geom. Таким образом, aes по умолчанию, обязательные aes и другие аргументы, которые вы указываете в ggproto, автоматически копируются / наследуются из этого geom, и вам не нужно вручную указывать их все.

person teunbrand    schedule 17.07.2019