metR icon indicating copy to clipboard operation
metR copied to clipboard

Suggestion for `geom_vector()` key glyphs

Open teunbrand opened this issue 5 months ago • 3 comments

When using geom_vector() + scale_mag(), you get a legend displaying the magnitude. This is fine, but I can imagine maintaining guide_vector() might be a bit of a hassle (certainly given recent guide kerfuffle).

library(ggplot2)
library(metR)

ggplot(seals, aes(long, lat)) +
  geom_vector(aes(dx = delta_long, dy = delta_lat), skip = 2) +
  scale_mag()
#> Warning: The S3 guide system was deprecated in ggplot2 3.5.0.
#> ℹ It has been replaced by a ggproto system that can be extended.
#> This warning is displayed once every 8 hours.
#> Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
#> generated.

So the suggestion I'd like to put out there, is that you can use a gimmick in ggplot2 >3.5.0 that lets you assign size to legend glyphs. That way, you can just use regular legends and you're able to display multiple breaks if needed. As a quick and dirty demo, here is how that might work:

draw_key_vector <- function(data, params, size) {
  if (is.null(data$linetype)) {
    data$linetype <- 0
  } else {
    data$linetype[is.na(data$linetype)] <- 0
  }

  `%||%` <- function(a, b) if (is.null(a)) b else a
    
  grob <- grid::segmentsGrob(
    x0 = 0.1, y0 = 0.5, x1 = unit(0.1, "npc") + unit(data$mag, "cm"), y1 = 0.5,
    gp = grid::gpar(
      col = alpha(data$colour %||% data$fill %||% "black", data$alpha),
      fill = alpha(params$arrow.fill %||% data$colour %||% data$fill %||% "black", data$alpha),
      lwd = (data$linewidth %||% 0.5) * .pt,
      lty = data$linetype %||% 1,
      lineend = params$lineend %||% "butt"
    ),
    arrow = params$arrow
  )
  # Magick number is 1.25 because we like to span 80% of the width with the segment, so the
  # total width is 1 / 0.8 * size == 1.25 * size
  attr(grob, "width") <- 1.25 * data$mag # assumes cm
  grob
  
}

ggplot(seals, aes(long, lat)) +
    geom_vector(aes(dx = delta_long, dy = delta_lat), 
                skip = 2, key_glyph = draw_key_vector) +
    continuous_scale("mag", palette = scales::identity_pal())

Created on 2024-01-19 with reprex v2.1.0

No need to implement this of course, but as I've been rummaging around metR this idea struck me and thought I'd share.

teunbrand avatar Jan 19 '24 15:01 teunbrand