Skip to content

Make legend glyphs configurable #3145

Closed
@clauswilke

Description

@clauswilke

Currently all geoms have a hard-coded legend glyph that can't be changed without some knowledge about the inner workings of ggplot2. It would be helpful if the glyphs could be configurable. Associated with such a change, we might want to provide a broader array of different glyphs. One example is the stylized time series glyph of PR #3124.

It seems to me the easiest way to achieve this modification is to provide an additional parameter draw_key to the constructor of each geom. The downside is that it requires a modification of each individual geom_*() and will not automatically propagate to extension packages. The upside is that the modification required is rather minor. Example implementation follows.

library(ggplot2)

# alternative key glyph
draw_key_timeseries <- function(data, params, size) {
  data$linetype[is.na(data$linetype)] <- 0

  grid::linesGrob(
    x = c(0, 0.4, 0.6, 1),
    y = c(0.1, 0.6, 0.4, 0.9),
    gp = grid::gpar(
      col = scales::alpha(data$colour, data$alpha),
      lwd = data$size * .pt,
      lty = data$linetype,
      lineend = "butt"
    )
  )
}

# helper function
set_draw_key <- function(geom, draw_key = NULL) {
  if (is.null(draw_key)) {
    return(geom)
  }
  if (is.character(draw_key)) {
    draw_key <- paste0("draw_key_", draw_key)
  }
  draw_key <- match.fun(draw_key)
  
  ggproto("", geom, draw_key = draw_key)
}

# version of `geom_line()` with modifiable draw key
geom_line2 <- function(mapping = NULL, data = NULL, stat = "identity",
                       position = "identity", na.rm = FALSE,
                       show.legend = NA, inherit.aes = TRUE, draw_key = NULL,
                       ...) {
  layer(
    data = data,
    mapping = mapping,
    stat = stat,
    geom = set_draw_key(GeomLine, draw_key),
    position = position,
    show.legend = show.legend,
    inherit.aes = inherit.aes,
    params = list(
      na.rm = na.rm,
      ...
    )
  )
}

# usage
base <- ggplot(data.frame(x = 1:3, y = 3:1), aes(x, y))
base + geom_line2(aes(color = "default"))

base + geom_line2(aes(color = "modified"), draw_key = "timeseries")

base + geom_line2(aes(color = "modified"), draw_key = draw_key_timeseries)

Created on 2019-02-15 by the reprex package (v0.2.1)

Metadata

Metadata

Assignees

No one assigned

    Labels

    featurea feature request or enhancement

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions