Suggestion for `geom_vector()` key glyphs
Closed this issue · 5 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.
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.
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.
That's great. I will defer this to a bit later after 3.5.0 is updated, then.
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.
This is now implemented! It limits some of the flexibility, but I think it's a much better fit for ggplot2.