I am trying to create geom_observation
, which annotates the plot with the number of observations in each group, but I am struggling with the positioning of the annotation.
I would like the position to be based on the "global" data-set, and not the grouped/faceted data-set. Further, I would like to achieve this without assigning the plot (i.e. p <- ggplot(...))
.
Lets have a look at the code:
library(tidyverse)
StatObservation <- ggproto("StatObservation", Stat,
compute_group = function(data, scales) {
data %>%
summarize(cnt=n(), x = max(data$x), y = max(data$y)) %>%
mutate(label = paste("n =", cnt), .keep="unused")
},
required_aes = c("x", "y")
)
GeomObservation <- ggproto("GeomObservation", GeomText,
default_aes = aes(
colour = "red", size = 4, angle = 0, hjust = "right", vjust = "top",
alpha = NA, family = "", fontface = 1, lineheight = 1.2
)
)
geom_observation <- function(mapping = NULL, data = NULL, position = "identity",
na.rm = FALSE, show.legend = NA, inherit.aes = TRUE, ...) {
layer(
stat = StatObservation, geom = GeomObservation, data = data, mapping = mapping,
position = position, show.legend = show.legend, inherit.aes = inherit.aes,
params = list(na.rm = na.rm, ...)
)
}
And the plots (I know I am assigning the plot here, but that is only to make the code more easily understandable):
# standard plot
p <- mpg %>%
# filter(manufacturer == "audi") %>%
ggplot(aes(x = cty, y = hwy)) +
geom_point() +
facet_grid(drv ~ factor(year))
p
# plot with poorly positioned annotations
p + geom_observation()
# plot with correctly positioned annotations
p + geom_observation(
aes(x = max(p$data[[rlang::get_expr(p$mapping$x)]]),
y = max(p$data[[rlang::get_expr(p$mapping$y)]]))
)
How can I achieve the result above without assigning the plot?
BONUS QUESTION (in case we solve the main question): How to handle with colour aesthetics?
- How to align the annotation above/below each other?
- Is it possible to re-group the colors, i.e. as if aes(colour) was not assigned?
p + aes(colour = class) +
geom_observation(
aes(x = max(p$data[[rlang::get_expr(p$mapping$x)]]),
y = max(p$data[[rlang::get_expr(p$mapping$y)]]))
)