Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Render arbitrary sets of icons #2

Open
jimjam-slam opened this issue Sep 5, 2017 · 4 comments
Open

Render arbitrary sets of icons #2

jimjam-slam opened this issue Sep 5, 2017 · 4 comments

Comments

@jimjam-slam
Copy link
Owner

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.

@baptiste
Copy link

I kind of have something along those lines in egg::geom_custom but it's not on CRAN because it requires a newer ggplot2

@jimjam-slam
Copy link
Owner Author

That sounds interesting! is it hosted on GitHub?

@baptiste
Copy link

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")
)

@jimjam-slam
Copy link
Owner Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants