Render arbitrary sets of icons
A logical extension of this package would be a geom that renders an arbitrary set of icons, specified by supplying a named vector of paths to a scale like:
my_icons = c(
'soccer' = 'icons/soccer.svg',
'rugby' = 'icons/rugby.svg',
'basketball' = 'icons/basketball.svg')
sportevents = ggplot(data) +
geom_icon(aes(x = longitude, y = latitude, size = interest, icon = sport)) +
scale_icon(values = my_icons)
This would be similar to the way custom colour scales are implemented. I think this could be done either with rastered PNG icons, building on baptiste/ggflags, or with vector SVG icons if I implemented #1.
I kind of have something along those lines in egg::geom_custom but it's not on CRAN because it requires a newer ggplot2
That sounds interesting! is it hosted on GitHub?
privately – I regularly get sick of random "issues" posted by strangers. The idea is to use list-columns to map grobs (or arbitrary data to draw a grob) as a "data" aesthetic.
#' geom_custom
#'
#' @param mapping mapping
#' @param data data
#' @param inherit.aes inherit.aes
#' @param ... arguments passed to the geom's draw_group method
#'
#' @importFrom gtable gtable_matrix gtable_add_grob gtable_add_cols gtable_add_rows
#' @importFrom grid nullGrob unit grobTree editGrob
#' @importFrom ggplot2 ggproto ggproto_parent layer
#' @return layer
#' @export
#' @examples
#' library(grid)
#' d <- data.frame(x=rep(1:3, 4), f=rep(letters[1:4], each=3))
#' gl <- replicate(4, matrix(sample(palette(), 9, TRUE), 3, 3), FALSE)
#' dummy <- data.frame(f=letters[1:4], data = I(gl))
#'
#' ggplot(d, aes(f,x)) +
#' facet_wrap(~f)+
#' theme_bw() +
#' geom_point()+
#' geom_custom(data = dummy, aes(data = data, y = 2),
#' grob_fun = function(x) rasterGrob(x, interpolate = FALSE,
#' width=unit(1,"cm"),
#' height=unit(1,"cm")))
geom_custom <- function(mapping = NULL,
data = NULL,
inherit.aes = TRUE,
...) {
layer(
geom = GeomCustom,
mapping = mapping,
data = data,
stat = "identity",
position = "identity",
show.legend = FALSE,
inherit.aes = inherit.aes,
params = list(...)
)
}
GeomCustom <- ggproto(
"GeomCustom",
Geom,
setup_data = function(self, data, params) {
data <- ggproto_parent(Geom, self)$setup_data(data, params)
data
},
draw_group = function(data, panel_scales, coord, grob_fun, fun_params=list()) {
coords <- coord$transform(data, panel_scales)
gl <- lapply(
seq_along(data$data),
function(i) {
.g <- do.call(grob_fun, c(list(data$data[[i]]), fun_params))
grid::editGrob(
.g,
x = unit(coords$x[i], "native"),
y = unit(coords$y[i], "native")
)
}
)
ggplot2:::ggname("geom_custom", do.call(grobTree, gl))
},
required_aes = c("data", "x", "y")
)
Oh, nice! Yeah, you might've seen over on the other issue, but I was thinking of moving the flags list into a df (especially since it could potentially support multiple "fonts" that way). Not super high priority, though; gotta iron out these SVG rendering issues first.