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

Scale palettes from theme #5946

Open
wants to merge 23 commits into
base: main
Choose a base branch
from
Open

Conversation

teunbrand
Copy link
Collaborator

@teunbrand teunbrand commented Jun 18, 2024

This is a proof-of-concept PR for a part of #2239 and fix #4696.

It explores setting scale palettes from the theme. When a scale has a NULL palette, the palette will be retrieved from the theme. In the theme, palettes can be provided for different aesthetic/discreteness combinations. Currently, only aesthetics for which this is implemented are colour and fill.

Some demos of this mechanism:

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

p <- ggplot(mpg, aes(displ, hwy)) +
  geom_point(aes(colour = class)) +
  discrete_scale("colour", palette = NULL)

# Using a palette function
p + theme(palette.colour.discrete = pal_viridis(option = "H"))

# Using a palette name
p + theme(palette.colour.discrete = "hue")

# Using a vector of colours
colours <- palette.colors(7, palette = "Okabe-Ito")
p + theme(palette.colour.discrete = colours)

Created on 2024-06-18 with reprex v2.1.0

The idea is that we'd have the default scales, e.g. scale_colour_discrete(), scale_colour_continuous() etc. have NULL palettes so that this mechanism kicks in. I'd still have to figure out how to do this in a backwards compatible manner though.

@teunbrand

This comment was marked as resolved.

@teunbrand
Copy link
Collaborator Author

teunbrand commented Jun 19, 2024

The default colour/fill scales like scale_colour_discrete(), scale_fill_continuous() etc. now all produce a scale where palette = NULL and thus theme palettes are invoked. For that reason, we wouldn't need to invoke a special scale here:

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

p <- ggplot(mpg, aes(displ, hwy)) +
  geom_point(aes(colour = class)) +
  theme(
    palette.colour.discrete = pal_brewer("qual")
  )

p

The old way of specifying default scales through options() is reasonably preserved.
Some areas where backwards compatibility does not hold completely:

  • Error messages no longer suggest alternatives for the type argument.
  • If a scale is used outside plots to map variables, a NULL palette might throw an error.
  • The default scale_colour_discrete() scale no longer constructs a scale_colour_hue(), so arguments like h, c and l are not passed on.
    If we're happy with the way the theme() route for palettes work, we could consider deprecating the options() route.
options("ggplot2.discrete.colour" = scale_colour_viridis_d)

p

Created on 2024-06-19 with reprex v2.1.0

@teunbrand
Copy link
Collaborator Author

teunbrand commented Jun 21, 2024

Now supports all vanilla non-position aesthetics.
Extension aesthetics can be added by using register_theme_elements(), where fallback palettes can be set as part of the specifications.

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

register_theme_elements(
  palette.foobar.discrete = function(n) seq(0.1, 1, length.out = n),
  element_tree = list(
    palette.foobar.discrete   = el_def(c("character", "numeric", "integer", "function"))
  )
)

fallback_palette("foobar", discrete = TRUE)
#> function(n) seq(0.1, 1, length.out = n)

Created on 2024-06-21 with reprex v2.1.0

I'll bump this from POC to WIP.

@teunbrand teunbrand changed the title POC: Scale palettes from theme WIP: Scale palettes from theme Jun 21, 2024
@teunbrand
Copy link
Collaborator Author

Should now work with the new scales::as_discrete_pal() and scales::as_continuous_pal().
The named version of specifying palettes doesn't currently work until r-lib/scales#448 gets merged.
Bumping this from WIP to ready for review

@teunbrand teunbrand marked this pull request as ready for review October 3, 2024 08:11
@teunbrand teunbrand changed the title WIP: Scale palettes from theme Scale palettes from theme Oct 3, 2024
@teunbrand teunbrand mentioned this pull request Oct 31, 2024
5 tasks
Merge branch 'main' into scale_palettes

# Conflicts:
#	tests/testthat/test-guides.R
R/scales-.R Outdated

# Resolve palette theme setting for this scale
type <- if (scale$is_discrete()) "discrete" else "continuous"
elem <- paste0("palette.", scale$aesthetics[1], ".", type)
Copy link
Member

Choose a reason for hiding this comment

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

In the case the scale has 2 aesthetics, say c("colour", "fill"), it will only look for palette.colour.<type>. Shouldn't it look for the first match instead?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yeah that is a good idea, thanks!

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

Successfully merging this pull request may close these issues.

Option to make default colour schemes accessible?
2 participants