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 guide #5496

Merged
merged 13 commits into from
Dec 4, 2023
Merged

Custom guide #5496

merged 13 commits into from
Dec 4, 2023

Conversation

teunbrand
Copy link
Collaborator

@teunbrand teunbrand commented Oct 26, 2023

This PR aims to fix #5416.

Briefly, it introduces guide_custom() for drawing arbitrary grobs alongside regular legends.

In some more detail:

  • It required new plumbing in Guides$build() because these guides don't have associated scales that train them (nor should they, but the assumption was that there is a scale associated to a guide).
  • Guide itself is essentially building a gtable around the grob with legend margins and a title.

A demonstration:

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

# Making a grob
n <- 5
t <- seq(0, 2 * pi, length.out = n * 2 + 1)[-(n * 2 + 1)]
l <- rep(c(1, 0.4), length.out = length(t))
x <- cos(t) * l
y <- sin(t) * l
mid <- unit(0.5, "npc")
grob <- polygonGrob(x = unit(x, "cm") + mid, y = unit(y, "cm") + mid)

# Displaying grob as guide
ggplot(mpg, aes(displ, hwy, colour = factor(cyl))) +
  geom_point() +
  guides(foo = guide_custom(grob, title = "star"))

I also realised that it makes it easy to make inset plots with this guide, as you can just pass a rendered plot as the grob.

p <- ggplot(mpg, aes(class, displ)) + geom_boxplot()

ggplot(mpg, aes(displ, hwy)) +
  geom_point() +
  guides(foo = guide_custom(
    ggplotGrob(p), title = "inset plot",
    width = unit(6, "cm"), height = unit(4, "cm")
  )) +
  theme(legend.position = c(1, 1), legend.justification = c(1, 1),
        legend.background = element_blank())

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

@thomasp85
Copy link
Member

While possible I don't think we should advocate the latter use as it muddies the whole guide concept

@teunbrand
Copy link
Collaborator Author

Yeah agreed, but I don't think we should disallow it either because it has some use-cases. One of them is if you plot a map of a country and you'd want to display the world as a guide, highlighting the country.

@teunbrand
Copy link
Collaborator Author

Adapted the PR to plumbing in #5483

@teunbrand teunbrand changed the title WIP: Custom guide Custom guide Nov 9, 2023
@teunbrand teunbrand requested a review from thomasp85 November 9, 2023 13:38
@teunbrand teunbrand added this to the ggplot2 3.5.0 milestone Nov 9, 2023
Comment on lines -97 to +98
# Assign empty guides if there are no non-position scales
plot$guides <- guides_list()
# Only keep custom guides if there are no non-position scales
plot$guides <- plot$guides$get_custom()
Copy link
Member

Choose a reason for hiding this comment

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

Can you elaborate on this change?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Sure, in the absence of non-position (NP) scales, we still want to render the custom guides.
Previously, if there were no NP scales, there'd be no need to render any NP guides, so we could set the guides list to empty (as position guides have been absorbed already by the coord).
However, since custom guides aren't attached to a scale, setting the guides list to empty would also discard the custom guides. Instead, we extract only the custom guides if there are no NP scales. In absence of any custom guides, the plot$guides$get_custom() just returns an empty guides list.

teunbrand and others added 3 commits December 4, 2023 16:24
Merge branch 'main' into guide_custom

# Conflicts:
#	man/ggplot2-ggproto.Rd
@teunbrand teunbrand merged commit 3765b97 into tidyverse:main Dec 4, 2023
12 checks passed
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.

Feature Request: guide_custom()
2 participants