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

Suggestion for geom_vector() key glyphs #186

Closed
teunbrand opened this issue Jan 19, 2024 · 5 comments
Closed

Suggestion for geom_vector() key glyphs #186

teunbrand opened this issue Jan 19, 2024 · 5 comments

Comments

@teunbrand
Copy link
Contributor

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.

@eliocamp
Copy link
Owner

eliocamp commented Jan 20, 2024

Thanks! It could be a good alternative. The reason I implemented a single arrow legend is that this is how I often see it in the papers I read in atmospheric science. But other disciplines might have other conventions, so adding this option might be useful for them.

Wait, no, scratch that. This implementation would also allow the user to plot only one arrow by customising the breaks, right? In that case, I should probably switch to this.

@teunbrand
Copy link
Contributor Author

This implementation would also allow the user to plot only one arrow by customising the breaks, right?

Yes that's right. You control scale_mag() and you could have it just return 1 break by default.
I don't know the conventions of your field, so I can't really judge in any meaningful capacity.
Major caveat though is that this won't work in ggplot2 <3.5.0.

@eliocamp
Copy link
Owner

That's great. I will defer this to a bit later after 3.5.0 is updated, then.

@PanfengZhang
Copy link

That's great. I will defer this to a bit later after 3.5.0 is updated, then.

The arrow drawn is solid, but the legend is indeed hollow. How to solve this problem? Make the default legend the same as the one drawn.

@eliocamp
Copy link
Owner

This is now implemented! It limits some of the flexibility, but I think it's a much better fit for ggplot2.

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

3 participants