Skip to content

Make legend glyphs configurable #3145

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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions