Skip to content

Refactor guide styling #5554

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

Merged
merged 28 commits into from
Dec 13, 2023
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
7f4a6a8
add more legend theme settings
teunbrand Nov 29, 2023
6751a66
remove elements as part of guide construction
teunbrand Nov 30, 2023
36136a3
add `theme` as required guide parameter
teunbrand Nov 30, 2023
3425f5b
bequeath axes with `theme` argument
teunbrand Nov 30, 2023
4f37180
wire `theme` into legends
teunbrand Nov 30, 2023
bf70ff9
impart `theme` upon colourbars
teunbrand Nov 30, 2023
de32582
entrust bins guide with `theme`
teunbrand Nov 30, 2023
854bca7
replacement utility
teunbrand Nov 30, 2023
21a000b
redocument
teunbrand Dec 1, 2023
72bcd1c
small tweaks
teunbrand Dec 1, 2023
3783e2e
backward compatibility mechanism
teunbrand Dec 1, 2023
9f8c0a7
add news bullet
teunbrand Dec 1, 2023
f2b872a
update tests
teunbrand Dec 1, 2023
d35f5be
Separate colourbar/coloursteps constructors
teunbrand Dec 1, 2023
ec87aa3
themes have default `legend.key.spacing`
teunbrand Dec 1, 2023
064bdcd
doc fixes
teunbrand Dec 1, 2023
014641d
resolve merge conflict
teunbrand Dec 1, 2023
86efab5
Merge branch 'main' into guide_themes
teunbrand Dec 7, 2023
2d9e7fc
add `theme` to stacked axis
teunbrand Dec 7, 2023
33897ae
There is no need for `justify_grobs()`
teunbrand Dec 7, 2023
8470aa2
resolve merge conflict
teunbrand Dec 8, 2023
4ee4cfb
update `replace_null()`
teunbrand Dec 8, 2023
6530b3c
fix examples
teunbrand Dec 8, 2023
9b2ae17
resolve merge conflict
teunbrand Dec 11, 2023
a14493b
adapt to latest changes
teunbrand Dec 11, 2023
b16a1bb
rename argument
teunbrand Dec 11, 2023
dad2815
Fix typo
teunbrand Dec 11, 2023
23b74f2
no need to use `justify_grobs()`
teunbrand Dec 11, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ Collate:
'grob-dotstack.R'
'grob-null.R'
'grouping.R'
'theme-elements.R'
'guide-.R'
'guide-axis.R'
'guide-axis-logticks.R'
Expand Down Expand Up @@ -265,7 +266,6 @@ Collate:
'stat-ydensity.R'
'summarise-plot.R'
'summary.R'
'theme-elements.R'
'theme.R'
'theme-defaults.R'
'theme-current.R'
Expand Down
7 changes: 7 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# ggplot2 (development version)

* `guide_*()` functions get a new `theme` argument to style individual guides.
The `theme()` function has gained additional arguments for styling guides:
`legend.key.spacing{.x/.y}`, `legend.frame`, `legend.axis.line`,
`legend.ticks`, `legend.ticks.length`, `legend.text.position` and
`legend.title.position`. Previous style arguments in the `guide_*()` functions
have been soft-deprecated.

* The `legend.key` theme element is set to inherit from the `panel.background`
theme element. The default themes no longer set the `legend.key` element.
This causes a visual change with the default `theme_gray()` (#5549).
Expand Down
22 changes: 14 additions & 8 deletions R/guide-.R
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
#' @include theme-elements.R
NULL

#' Guide constructor
#'
#' A constructor function for guides, which performs some standard compatibility
Expand Down Expand Up @@ -25,13 +28,8 @@ new_guide <- function(..., available_aes = "any", super) {
params <- intersect(names(args), param_names)
params <- defaults(args[params], super$params)

# Set elements
elems_names <- names(super$elements)
elems <- intersect(names(args), elems_names)
elems <- defaults(args[elems], super$elements)

# Warn about extra arguments
extra_args <- setdiff(names(args), union(param_names, elems_names))
extra_args <- setdiff(names(args), param_names)
if (length(extra_args) > 0) {
cli::cli_warn(paste0(
"Ignoring unknown {cli::qty(extra_args)} argument{?s} to ",
Expand All @@ -50,14 +48,20 @@ new_guide <- function(..., available_aes = "any", super) {
))
}

# Validate theme settings
if (!is.null(params$theme)) {
check_object(params$theme, is.theme, what = "a {.cls theme} object")
validate_theme(params$theme)
params$direction <- params$direction %||% params$theme$legend.direction
}

# Ensure 'order' is length 1 integer
params$order <- vec_cast(params$order, 0L, x_arg = "order", call = pf)
vec_assert(params$order, 0L, size = 1L, arg = "order", call = pf)

ggproto(
NULL, super,
params = params,
elements = elems,
params = params,
available_aes = available_aes
)
}
Expand Down Expand Up @@ -162,6 +166,7 @@ Guide <- ggproto(
# `GuidesList` class.
params = list(
title = waiver(),
theme = NULL,
name = character(),
position = waiver(),
direction = NULL,
Expand Down Expand Up @@ -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.

is_char <- vapply(elements, is.character, logical(1))
elements[is_char] <- lapply(elements[is_char], calc_element, theme = theme)
elements
Expand Down
2 changes: 2 additions & 0 deletions R/guide-axis-logticks.R
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ guide_axis_logticks <- function(
short_theme = element_line(),
expanded = TRUE,
cap = "none",
theme = NULL,
...
) {
if (is.logical(cap)) {
Expand Down Expand Up @@ -108,6 +109,7 @@ guide_axis_logticks <- function(
cap = cap,
minor.ticks = TRUE,
short_theme = short_theme,
theme = theme,
...,
super = GuideAxisLogticks
)
Expand Down
2 changes: 1 addition & 1 deletion R/guide-axis-theta.R
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ NULL
#'
#' # The `angle` argument can be used to set relative angles
#' p + guides(theta = guide_axis_theta(angle = 0))
guide_axis_theta <- function(title = waiver(), angle = waiver(),
guide_axis_theta <- function(title = waiver(), theme = NULL, angle = waiver(),
minor.ticks = FALSE, cap = "none", order = 0,
position = waiver()) {

Expand Down
25 changes: 12 additions & 13 deletions R/guide-axis.R
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@
#'
#' # can also be used to add a duplicate guide
#' p + guides(x = guide_axis(n.dodge = 2), y.sec = guide_axis())
guide_axis <- function(title = waiver(), check.overlap = FALSE, angle = waiver(),
n.dodge = 1, minor.ticks = FALSE, cap = "none",
order = 0, position = waiver()) {
guide_axis <- function(title = waiver(), theme = NULL, check.overlap = FALSE,
angle = waiver(), n.dodge = 1, minor.ticks = FALSE,
cap = "none", order = 0, position = waiver()) {
check_bool(minor.ticks)
if (is.logical(cap)) {
check_bool(cap)
Expand All @@ -58,6 +58,7 @@ guide_axis <- function(title = waiver(), check.overlap = FALSE, angle = waiver()

new_guide(
title = title,
theme = theme,

# customisations
check.overlap = check.overlap,
Expand Down Expand Up @@ -86,6 +87,7 @@ GuideAxis <- ggproto(

params = list(
title = waiver(),
theme = NULL,
name = "axis",
hash = character(),
position = waiver(),
Expand Down Expand Up @@ -225,17 +227,14 @@ GuideAxis <- ggproto(
},

setup_elements = function(params, elements, theme) {
axis_elem <- c("line", "text", "ticks", "minor", "major_length", "minor_length")
is_char <- vapply(elements[axis_elem], is.character, logical(1))
axis_elem <- axis_elem[is_char]
elements[axis_elem] <- lapply(
paste(
unlist(elements[axis_elem]),
params$aes, params$position, sep = "."
),
calc_element, theme = theme
is_char <- vapply(elements, is.character, logical(1))
suffix <- paste(params$aes, params$position, sep = ".")
elements[is_char] <- vapply(
elements[is_char],
function(x) paste(x, suffix, sep = "."),
character(1)
)
elements
Guide$setup_elements(params, elements, theme)
},

override_elements = function(params, elements, theme) {
Expand Down
Loading