ggplot2:来自 draw_panel 的 return 值

ggplot2: return value from draw_panel

我正在学习使用 ggplot2 编写代码。我希望创建一个新的 geom,它使某些东西变得复杂——而不是一个简单的多边形。比如,中间有一个点的矩形。

当我定义我的新 geom 对象时,比如 GeomFafik,我需要指定函数 draw_panel(或 draw_group,或任何一个)returns a grob. Here is how it looks now (based on the extending ggplot2 小插图:

GeomFafik <- ggproto("GeomFafik", 
               Geom, 
               required_aes=c("xmin", "ymin", "xmax", "ymax"),
               default_aes=aes(shape=19, colour="black"),
               draw_key=draw_key_blank(),
               draw_panel=function(data, panel_params, coord) {
                  coords <- coord$transform(data, panel_params)
                  # how can I combine grob1 with grob2 and 
                  # return the result?
                  grob1 <- grid::rectGrob(coords$xmin, coords$ymin,
                                          width=coords$xmax - coords$xmin, 
                                          height=coords$ymax - coords$ymin,
                                          gp=gpar(col=coord$colour))
                  grob2 <- grid::pointsGrob(x=coords$xmin + (coords$xmax - coords$xmin)/2,
                                            y=coords$ymin + (coords$ymax - coords$ymax)/2,
                                            gp=gpar(col=coord$colour))
               })

我应该使用 grob()gTree()grid 构建一个 grob 是对的吗?或者是否有 ggplot2 方法(类似于 zeroGrob)?如果 grid,那么我应该使用两者中的哪一个?我在哪里可以找到例子? manual page 真的没什么好说的。

好的,这比我想象的要容易。解决方案是按如下方式使用 gTree(感谢 this 示例):

GeomFafik <- ggproto("GeomFafik",
               Geom, 
               required_aes=c("xmin", "ymin", "xmax", "ymax"),
               default_aes=aes(shape=19, colour="black"),
               draw_key=draw_key_blank(),
               draw_panel=function(data, panel_params, coord) {

                  coords <- coord$transform(data, panel_params)

                  w <- coords$xmax - coords$xmin
                  h <- coords$ymax - coords$ymin
                  x <- coords$xmin + w/2
                  y <- coords$ymin + h/2
                  grob1 <- grid::rectGrob(x, y, width=w, height=h,
                                          gp=gpar(col=coord$colour))
                  grob2 <- grid::pointsGrob(x=x, y=y,
                                            gp=gpar(col=coord$colour))
                  grid::gTree("fafik_grob", children=grid::gList(grob1, grob2))
               })


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

结果,正是我想要的: