Skip to content

Commit 8e1c085

Browse files
authored
Refactor guide styling (#5554)
* add more legend theme settings * remove elements as part of guide construction * add `theme` as required guide parameter * bequeath axes with `theme` argument * wire `theme` into legends * impart `theme` upon colourbars * entrust bins guide with `theme` * replacement utility * redocument * small tweaks * backward compatibility mechanism * add news bullet * update tests * Separate colourbar/coloursteps constructors * themes have default `legend.key.spacing` * doc fixes * add `theme` to stacked axis * There is no need for `justify_grobs()` * update `replace_null()` * fix examples * adapt to latest changes * rename argument * Fix typo * no need to use `justify_grobs()`
1 parent 61142ae commit 8e1c085

29 files changed

+778
-1101
lines changed

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ Collate:
175175
'grob-dotstack.R'
176176
'grob-null.R'
177177
'grouping.R'
178+
'theme-elements.R'
178179
'guide-.R'
179180
'guide-axis.R'
180181
'guide-axis-logticks.R'
@@ -269,7 +270,6 @@ Collate:
269270
'stat-ydensity.R'
270271
'summarise-plot.R'
271272
'summary.R'
272-
'theme-elements.R'
273273
'theme.R'
274274
'theme-defaults.R'
275275
'theme-current.R'

NEWS.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# ggplot2 (development version)
22

3+
* `guide_*()` functions get a new `theme` argument to style individual guides.
4+
The `theme()` function has gained additional arguments for styling guides:
5+
`legend.key.spacing{.x/.y}`, `legend.frame`, `legend.axis.line`,
6+
`legend.ticks`, `legend.ticks.length`, `legend.text.position` and
7+
`legend.title.position`. Previous style arguments in the `guide_*()` functions
8+
have been soft-deprecated.
9+
310
* When legend titles are larger than the legend, title justification extends
411
to the placement of keys and labels (#1903).
512

R/guide-.R

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
#' @include theme-elements.R
2+
NULL
3+
14
#' Guide constructor
25
#'
36
#' A constructor function for guides, which performs some standard compatibility
@@ -25,13 +28,8 @@ new_guide <- function(..., available_aes = "any", super) {
2528
params <- intersect(names(args), param_names)
2629
params <- defaults(args[params], super$params)
2730

28-
# Set elements
29-
elems_names <- names(super$elements)
30-
elems <- intersect(names(args), elems_names)
31-
elems <- defaults(args[elems], super$elements)
32-
3331
# Warn about extra arguments
34-
extra_args <- setdiff(names(args), union(param_names, elems_names))
32+
extra_args <- setdiff(names(args), param_names)
3533
if (length(extra_args) > 0) {
3634
cli::cli_warn(paste0(
3735
"Ignoring unknown {cli::qty(extra_args)} argument{?s} to ",
@@ -50,14 +48,20 @@ new_guide <- function(..., available_aes = "any", super) {
5048
))
5149
}
5250

51+
# Validate theme settings
52+
if (!is.null(params$theme)) {
53+
check_object(params$theme, is.theme, what = "a {.cls theme} object")
54+
validate_theme(params$theme)
55+
params$direction <- params$direction %||% params$theme$legend.direction
56+
}
57+
5358
# Ensure 'order' is length 1 integer
5459
params$order <- vec_cast(params$order, 0L, x_arg = "order", call = pf)
5560
vec_assert(params$order, 0L, size = 1L, arg = "order", call = pf)
5661

5762
ggproto(
5863
NULL, super,
59-
params = params,
60-
elements = elems,
64+
params = params,
6165
available_aes = available_aes
6266
)
6367
}
@@ -162,6 +166,7 @@ Guide <- ggproto(
162166
# `GuidesList` class.
163167
params = list(
164168
title = waiver(),
169+
theme = NULL,
165170
name = character(),
166171
position = waiver(),
167172
direction = NULL,
@@ -275,6 +280,7 @@ Guide <- ggproto(
275280
# Converts the `elements` field to proper elements to be accepted by
276281
# `element_grob()`. String-interpolates aesthetic/position dependent elements.
277282
setup_elements = function(params, elements, theme) {
283+
theme <- add_theme(theme, params$theme)
278284
is_char <- vapply(elements, is.character, logical(1))
279285
elements[is_char] <- lapply(elements[is_char], calc_element, theme = theme)
280286
elements
@@ -294,8 +300,7 @@ Guide <- ggproto(
294300
key <- params$key
295301

296302
# Setup parameters and theme
297-
params$position <- params$position %||% position
298-
params$direction <- params$direction %||% direction
303+
params <- replace_null(params, position = position, direction = direction)
299304
params <- self$setup_params(params)
300305
elems <- self$setup_elements(params, self$elements, theme)
301306
elems <- self$override_elements(params, elems, theme)

R/guide-axis-logticks.R

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ guide_axis_logticks <- function(
7272
short_theme = element_line(),
7373
expanded = TRUE,
7474
cap = "none",
75+
theme = NULL,
7576
...
7677
) {
7778
if (is.logical(cap)) {
@@ -108,6 +109,7 @@ guide_axis_logticks <- function(
108109
cap = cap,
109110
minor.ticks = TRUE,
110111
short_theme = short_theme,
112+
theme = theme,
111113
...,
112114
super = GuideAxisLogticks
113115
)

R/guide-axis-stack.R

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ NULL
2929
#'
3030
#' # A normal axis first, then a capped axis
3131
#' p + guides(x = guide_axis_stack("axis", guide_axis(cap = "both")))
32-
guide_axis_stack <- function(first = "axis", ..., title = waiver(),
32+
guide_axis_stack <- function(first = "axis", ..., title = waiver(), theme = NULL,
3333
spacing = NULL, order = 0, position = waiver()) {
3434

3535
check_object(spacing, is.unit, "{.cls unit}", allow_null = TRUE)
@@ -63,6 +63,7 @@ guide_axis_stack <- function(first = "axis", ..., title = waiver(),
6363

6464
new_guide(
6565
title = title,
66+
theme = theme,
6667
guides = axes,
6768
guide_params = params,
6869
available_aes = c("x", "y", "theta", "r"),
@@ -88,6 +89,7 @@ GuideAxisStack <- ggproto(
8889
# Standard guide stuff
8990
name = "stacked_axis",
9091
title = waiver(),
92+
theme = NULL,
9193
angle = waiver(),
9294
hash = character(),
9395
position = waiver(),
@@ -142,6 +144,7 @@ GuideAxisStack <- ggproto(
142144

143145
draw = function(self, theme, position = NULL, direction = NULL,
144146
params = self$params) {
147+
theme <- add_theme(theme, params$theme)
145148

146149
position <- params$position %||% position
147150
direction <- params$direction %||% direction

R/guide-axis-theta.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ NULL
2323
#'
2424
#' # The `angle` argument can be used to set relative angles
2525
#' p + guides(theta = guide_axis_theta(angle = 0))
26-
guide_axis_theta <- function(title = waiver(), angle = waiver(),
26+
guide_axis_theta <- function(title = waiver(), theme = NULL, angle = waiver(),
2727
minor.ticks = FALSE, cap = "none", order = 0,
2828
position = waiver()) {
2929

R/guide-axis.R

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@
4646
#'
4747
#' # can also be used to add a duplicate guide
4848
#' p + guides(x = guide_axis(n.dodge = 2), y.sec = guide_axis())
49-
guide_axis <- function(title = waiver(), check.overlap = FALSE, angle = waiver(),
50-
n.dodge = 1, minor.ticks = FALSE, cap = "none",
51-
order = 0, position = waiver()) {
49+
guide_axis <- function(title = waiver(), theme = NULL, check.overlap = FALSE,
50+
angle = waiver(), n.dodge = 1, minor.ticks = FALSE,
51+
cap = "none", order = 0, position = waiver()) {
5252
check_bool(minor.ticks)
5353
if (is.logical(cap)) {
5454
check_bool(cap)
@@ -58,6 +58,7 @@ guide_axis <- function(title = waiver(), check.overlap = FALSE, angle = waiver()
5858

5959
new_guide(
6060
title = title,
61+
theme = theme,
6162

6263
# customisations
6364
check.overlap = check.overlap,
@@ -86,6 +87,7 @@ GuideAxis <- ggproto(
8687

8788
params = list(
8889
title = waiver(),
90+
theme = NULL,
8991
name = "axis",
9092
hash = character(),
9193
position = waiver(),
@@ -225,17 +227,14 @@ GuideAxis <- ggproto(
225227
},
226228

227229
setup_elements = function(params, elements, theme) {
228-
axis_elem <- c("line", "text", "ticks", "minor", "major_length", "minor_length")
229-
is_char <- vapply(elements[axis_elem], is.character, logical(1))
230-
axis_elem <- axis_elem[is_char]
231-
elements[axis_elem] <- lapply(
232-
paste(
233-
unlist(elements[axis_elem]),
234-
params$aes, params$position, sep = "."
235-
),
236-
calc_element, theme = theme
230+
is_char <- vapply(elements, is.character, logical(1))
231+
suffix <- paste(params$aes, params$position, sep = ".")
232+
elements[is_char] <- vapply(
233+
elements[is_char],
234+
function(x) paste(x, suffix, sep = "."),
235+
character(1)
237236
)
238-
elements
237+
Guide$setup_elements(params, elements, theme)
239238
},
240239

241240
override_elements = function(params, elements, theme) {

0 commit comments

Comments
 (0)