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

Refactor guide styling #5554

Merged
merged 28 commits into from
Dec 13, 2023
Merged

Refactor guide styling #5554

merged 28 commits into from
Dec 13, 2023

Conversation

teunbrand
Copy link
Collaborator

@teunbrand teunbrand commented Dec 1, 2023

This PR aims to fix #5348 and also fixes #5539, fixes #5540 and fixes #5541 and implements #5473 (comment).

Briefly, it is quite a beefy PR that adds a theme argument to all guide_*() functions and adds guide style elements to theme().

Less briefly; I could not find a satisfactory way to simplify guide styling without breaking some backward compatibility. I attempted this in #5512, but that PR added as much complexity as it took away. The crux of the PR is this:

  • The theme() function has new arguments for styling guides, like legend.frame, legend.ticks etc.
  • guide_*() functions no longer have style arguments, like frame, ticks, etc.
  • To style individual guides, one can now use guide_*(theme = theme(...))

This allows one to change the look of an individual guide with, for example, a preset theme:

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

p <- ggplot(mpg, aes(displ, hwy)) +
  geom_point(aes(fill = cyl, colour = cty), shape = 21)

p + guides(fill = guide_legend(theme = theme_dark()))

In addition, all guide style options are now settable from the plot's theme:

red_frame <- theme(legend.frame = element_rect(colour = "red"))

p + red_frame

While retaining flexibility in individual guides.

p + guides(colour = guide_colourbar(theme = red_frame))

The 'old' options still work, but are passed through the ... argument and are undocumented.

p + guides(colour = guide_colourbar(frame.colour = "red"))

Also, the 'old' options are soft-deprecated so developers will start seeing warnings about them:

withr::with_options(
  list(lifecycle_verbosity = "error"),
  guide_colourbar(frame.colour = "red")
)
#> Error:
#> ! The `frame.colour` argument of `guide_colourbar()` is deprecated as of
#>   ggplot2 3.5.0.
#> ℹ Please use the `theme` argument instead.

Created on 2023-12-01 with reprex v2.0.2

Some additional notes:

  • theme() is already widely used to style non-data elements of the plot, so the way to style guides should be familiar.
  • The PR greatly reduced argument clutter in guides.
  • There is now harmony in which style element can be set from the guide and which element from the theme.
  • The inheritance logic is now clear: it is (plot_theme %||% guide_defaults) + guide_theme (with %||% applied element-wise, and + meaning add_theme()). This should allow for easier maintenance of the guides, as well as make it easier to extend guides.
  • Some legend styling options don't have plot-level defaults as different guides had different defaults that I preserved. For example, guide_colourbar() has white ticks by default, guide_bins() has black ticks by default and guide_coloursteps has hidden ticks by default.
  • We lose the 'expressions are right-aligned by default' heuristic. This is only a 'con' if you rely on this behaviour, it is less of a con if you, like me and others (Legend mis-alignement for parsing greek letters using scale::parse_format #4814) are surprised by this behaviour. Removing this heuristic is a net positive I think, as it is now far more straightforward to derive the horizontal justification for legend labels.
  • The legend.key.spacing is now set to the half the theme's base_size, which already is the default in 99% of legends except in the 1% where the legend doesn't have a title. Previously, it was half the title size, and if that was missing half the label size and if that was missing 5.5 points. This resulted in 1 visual snapshot without a legend title changing slightly. The additional text margins introduced in Rework legend spacing #5456 also derive from this setting for symmetry reasons.
  • A downside is that it is somewhat more verbose to set guide-level themes, but I think it is worth it overall.
  • If we ever want to get rid of guide code gnarlyness, now is the time to do it.

@@ -274,6 +279,7 @@ Guide <- ggproto(
# Converts the `elements` field to proper elements to be accepted by
# `element_grob()`. String-interpolates aesthetic/position dependent elements.
setup_elements = function(params, elements, theme) {
theme <- add_theme(theme, params$theme)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is the crucial step.

@teunbrand teunbrand added this to the ggplot2 3.5.0 milestone Dec 1, 2023
R/utilities.R Outdated Show resolved Hide resolved
Merge branch 'main' into guide_themes

# Conflicts:
#	R/guide-bins.R
#	R/guide-colorbar.R
#	R/guide-legend.R
#	R/theme-elements.R
#	R/theme.R
#	man/guide_bins.Rd
#	man/guide_coloursteps.Rd
#	man/guide_legend.Rd
#	man/theme.Rd
Merge branch 'main' into guide_themes

# Conflicts:
#	R/guide-colorbar.R
#	R/guide-legend.R
#	man/guide_bins.Rd
#	man/guide_colourbar.Rd
#	man/guide_coloursteps.Rd
#	man/guide_legend.Rd
R/utilities.R Outdated Show resolved Hide resolved
@thomasp85
Copy link
Member

a14493b is about the guide stretching stuff, right?

@teunbrand
Copy link
Collaborator Author

And long title placement, yes

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
Copy link
Collaborator Author

Thanks Thomas!

@teunbrand teunbrand merged commit 8e1c085 into tidyverse:main Dec 13, 2023
12 checks passed
@teunbrand teunbrand deleted the guide_themes branch December 13, 2023 09:04
teunbrand added a commit to teunbrand/ggplot2 that referenced this pull request Dec 20, 2023
@teunbrand teunbrand mentioned this pull request Dec 20, 2023
teunbrand added a commit that referenced this pull request Dec 22, 2023
* Apply #5554 to `guide_custom()`

* build in early exit
thomasp85 pushed a commit that referenced this pull request Feb 23, 2024
* Apply #5554 to `guide_custom()`

* build in early exit
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants