I am creating a custom geom and would like it to take an extra parameter, called showpoints
, which does something or other to the actual plot. For example, by setting it to FALSE, the geom actually returns a zeroGrob()
. I have found a way of doing that, but (i) it is clunky and somewhat weird and (ii) I don't fully understand what I am doing, which is a bad sign. The problem is that when you are defining a new stat, it is possible to run setup_params
, but geoms don't have it:
Compared to Stat and Position, Geom is a little different because the execution of the setup and compute functions is split up. setup_data runs before position adjustments, and draw_layer is not run until render time, much later. This means there is no setup_params because it's hard to communicate the changes.
[Source]
Basically, the code I have works in the sense that you can use the additional parameter to suppress drawing of the points:
# 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)
Here is my code so far, based on 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, ...)
)
}
Is there a simpler way of just passing a chosen extra param to the geom? If I can define extra_params
, why can't I access them somehow more easily?