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

Custom key glyph sizes #5465

Merged
merged 7 commits into from
Nov 22, 2023
Merged

Custom key glyph sizes #5465

merged 7 commits into from
Nov 22, 2023

Conversation

teunbrand
Copy link
Collaborator

This PR aims to fix a roadblock in #5454 by providing a mechanism by which keys can set custom sizes.

The problem is that it is heuristically okay, but sometimes inconvenient, for the legend key size to be determined by only the linewidth and size column in the data. For example, consider the following case when displaying arrows, where arrowhead size exceeds the allotted size on the legend:

devtools::load_all("~/packages/ggplot2")
#> ℹ Loading ggplot2

df <- data.frame(x = 0, xend = 1, y = 1:3, group = LETTERS[1:3])

p <- ggplot(df, aes(x, y, xend = xend, yend = y, colour = group))
p + geom_segment(arrow = arrow(length = unit(1, "cm")))

With this PR, key drawing functions can set their size by attaching a "width" and/or "height" attribute to the produced grob (in cm).
For example, for arrows we might sketch the following key drawing function, which incorporates the dimensions of the arrowhead in these attributes. (Note that this isn't quite perfect, since the glyphs go from 0.1npc to 0.9npc, but it illustrates the point)

draw_key_arrow <- function(data, params, size) {
  grob <- draw_key_path(data, params, size)
  if (!is.null(params$arrow)) {
    angle  <- params$arrow$angle / 180 * pi
    length <- grid::convertUnit(params$arrow$length, unitTo = "cm", valueOnly = TRUE)
    attr(grob, "width")  <- (cos(angle) * length) + 0.1
    attr(grob, "height") <- (sin(angle) * length * 2) + 0.1
  }
  grob
}

Now we can have less funky legend keys for the arrows:

p + geom_segment(arrow = arrow(length = unit(1, "cm"), angle = 15),
                 key_glyph = draw_key_arrow)

p + geom_segment(arrow = arrow(length = unit(1, "cm"), angle = 60),
                 key_glyph = draw_key_arrow)

Created on 2023-10-10 with reprex v2.0.2

@teunbrand
Copy link
Collaborator Author

Maybe instead of this being encoded in attributes, it would be better to use the viewport argument?

@thomasp85 thomasp85 added this to the ggplot2 3.5.0 milestone Oct 24, 2023
@teunbrand
Copy link
Collaborator Author

Maybe instead of this being encoded in attributes, it would be better to use the viewport argument

I experimented with this, but it is more of a hassle than as a solution. The main issue I'm encountering is that when setting a viewport on a key that doesn't have one based on the size or linewidth, it applies in both x- and y-directions,

@thomasp85 thomasp85 self-requested a review November 7, 2023 10:07
@teunbrand teunbrand changed the title Custom key sizes Custom key glyph sizes Nov 7, 2023
Copy link
Member

@thomasp85 thomasp85 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@teunbrand teunbrand merged commit a9983a8 into tidyverse:main Nov 22, 2023
12 checks passed
@teunbrand teunbrand deleted the key_sizes branch November 22, 2023 10:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants