扩展ggplot2:如何构建geom和stat?

时间:2018-12-26 11:09:31

标签: r ggplot2 proto ggproto

我正处于学习扩展ggplot2的早期阶段。我想创建一个自定义geom和关联的stat。我的出发点是vignette。另外,我从thisthis中受益。我正在尝试建立一个模板来自学,并希望别人能自学。

主要问题:

在函数calculate_shadows()中,所需的参数params$anchorNULL。我该如何访问它?

下面描述的目标仅用于学习如何创建自定义statgeom函数,这不是一个真正的目标:如您在屏幕截图中所见,我确实知道如何利用ggplot2的功效。

  1. geom将读取数据,并为提供的变量("x", "y")绘制(希望缺少更好的单词)shadows:一条水平线min(x)--max(x)默认为y=0,垂直线为min(y)--max(y)。如果提供了选件,则可以更改这些“锚点”,例如如果用户提供x=0,则水平线将在截距x = 35, y = 1处绘制,而垂直线将在截距y = 1处绘制。用法:

    x = 35

enter image description here

  1. library(ggplot2) ggplot(data = mtcars, aes(x = mpg, y = wt)) + geom_point() + geom_shadows(x = 35, y = 1) 将读取数据,并且对于提供的变量stat将根据("x", "y")的值计算shadows。例如,通过传递stat,将为数据的最小值和最大值计算阴影(由stat = "identity"完成)。但是通过传递geom_shadows,可以计算出第一和第三四分位数的阴影。更一般而言,可以传递带有参数stat = "quartile"的函数stats::quantile来使用第10个百分位数和第90个百分位数以及类型6的分位数方法来计算阴影。用法:

    args = list(probs = c(0.10, 0.90), type = 6)

enter image description here

很不幸,我对扩展ggplot(data = mtcars, aes(x = mpg, y = wt)) + geom_point() + stat_shadows(stat = "quartile") 的缺乏了解使我远远没有达到我的目标。这些情节被ggplot2“伪造”了。基于上面引用的教程和讨论,并检查了诸如geom_segmentstat-qq之类的现有代码,我为该目标构建了一个基本架构。它必须包含许多错误,我将不胜感激。另外,请注意,以下两种方法都可以:stat-smoothgeom_shadows(anchor = c(35, 1))

现在这是我的努力。首先,geom_shadows(x = 35, y = 1)定义geom-shadows.r。其次,用geom_shadows()来定义stat-shadows.r。该代码无法按原样工作。但是,如果我执行其内容,它将产生所需的统计信息。为了清楚起见,我删除了stat_shadows()中的大部分计算(例如四分位数),以重点关注基本要素。布局中有明显的错误吗?

geom-shadows.r

stat_shadows()

stat-shadows.r

#' documentation ought to be here
geom_shadows <- function(
  mapping = NULL, 
  data = NULL, 
  stat = "shadows", 
  position = "identity", 
  ...,
  anchor = list(x = 0, y = 0),
  shadows = list("x", "y"), 
  type = NULL,
  na.rm = FALSE,
  show.legend = NA, 
  inherit.aes = TRUE) {
    layer(
      data = data,
      mapping = mapping,
      stat = stat,
      geom = GeomShadows,
      position = position,
      show.legend = show.legend,
      inherit.aes = inherit.aes,
      params = list(
        anchor = anchor,
        shadows = shadows,
        type = type,  
        na.rm = na.rm,
        ...
    )
  )
}

GeomShadows <- ggproto("GeomShadows", Geom, 

  # set up the data, e.g. remove missing data
  setup_data = function(data, params) { 
    data 
  }, 

  # set up the parameters, e.g. supply warnings for incorrect input
  setup_params = function(data, params) {
    params
  },

  draw_group = function(data, panel_params, coord, anchor, shadows, type) { 
    # draw_group uses stats returned by compute_group

    # set common aesthetics
    geom_aes <- list(
      alpha = data$alpha,
      colour = data$color,
      size = data$size,
      linetype = data$linetype,
      fill = alpha(data$fill, data$alpha),
      group = data$group
    )

    # merge aesthetics with data calculated in setup_data
    geom_stats <- new_data_frame(c(list(
          x = c(data$x.xmin, data$y.xmin),
          xend = c(data$x.xmax, data$y.xmax),
          y = c(data$x.ymin, data$y.ymin),
          yend = c(data$x.ymax, data$y.ymax),
          alpha = c(data$alpha, data$alpha) 
        ), geom_aes
      ), n = 2) 

    # turn the stats data into a GeomPath
    geom_grob <- GeomSegment$draw_panel(unique(geom_stats), 
        panel_params, coord) 

    # pass the GeomPath to grobTree
    ggname("geom_shadows", grobTree(geom_grob)) 
  },

  # set legend box styles
  draw_key = draw_key_path,

  # set default aesthetics 
  default_aes = aes(
    colour = "blue",
    fill = "red",
    size = 1,
    linetype = 1,
    alpha = 1
  )

)

1 个答案:

答案 0 :(得分:0)

直到给出更彻底的答案:您丢失了

extra_params = c("na.rm", "shadows", "anchor", "type"),

GeomShadows <- ggproto("GeomShadows", Geom,

,也可能在StatShadows <- ggproto("StatShadows", Stat,内部。

geom-.rstat-.r内有许多非常有用的注释,这些注释阐明了几何和统计信息的工作方式。尤其要注意(在github上,克劳斯·威尔克(Claus Wilke)提出了建议):

# Most parameters for the geom are taken automatically from draw_panel() or
# draw_groups(). However, some additional parameters may be needed
# for setup_data() or handle_na(). These can not be imputed automatically,
# so the slightly hacky "extra_params" field is used instead. By
# default it contains `na.rm`
extra_params = c("na.rm"),