Skip to content

Commit 3109d11

Browse files
authored
Copy angle heuristic for more guides. (#5957)
* generalise angle heuristic * apply heuristic * parameter plumbing * document * add news bullet * digusting simplification * add comments for future generations * accept phase-shift in angles
1 parent 7ce155b commit 3109d11

12 files changed

+172
-152
lines changed

NEWS.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# ggplot2 (development version)
22

3+
* `guide_bins()`, `guide_colourbar()` and `guide_coloursteps()` gain an `angle`
4+
argument to overrule theme settings, similar to `guide_axis(angle)`
5+
(@teunbrand, #4594).
36
* `coord_*(expand)` can now take a logical vector to control expansion at any
47
side of the panel (top, right, bottom, left) (@teunbrand, #6020)
58
* (Breaking) The defaults for all geoms can be set at one in the theme.
@@ -24,7 +27,7 @@
2427
class through new `Coord$draw_panel()` method.
2528
* `theme(strip.clip)` now defaults to `"on"` and is independent of Coord
2629
clipping (@teunbrand, 5952).
27-
* (internal) rearranged the code of `Facet$draw_paensl()` method (@teunbrand).
30+
* (internal) rearranged the code of `Facet$draw_panels()` method (@teunbrand).
2831
* Axis labels are now justified across facet panels (@teunbrand, #5820)
2932
* Fixed bug in `stat_function()` so x-axis title now produced automatically
3033
when no data added. (@phispu, #5647).

R/guide-axis.R

Lines changed: 28 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -254,21 +254,8 @@ GuideAxis <- ggproto(
254254
},
255255

256256
override_elements = function(params, elements, theme) {
257-
label <- elements$text
258-
if (!inherits(label, "element_text")) {
259-
return(elements)
260-
}
261-
label_overrides <- axis_label_element_overrides(
262-
params$position, params$angle
263-
)
264-
# label_overrides is an element_text, but label_element may not be;
265-
# to merge the two elements, we just copy angle, hjust, and vjust
266-
# unless their values are NULL
267-
label$angle <- label_overrides$angle %||% label$angle
268-
label$hjust <- label_overrides$hjust %||% label$hjust
269-
label$vjust <- label_overrides$vjust %||% label$vjust
270-
271-
elements$text <- label
257+
elements$text <-
258+
label_angle_heuristic(elements$text, params$position, params$angle)
272259
return(elements)
273260
},
274261

@@ -584,49 +571,40 @@ axis_label_priority_between <- function(x, y) {
584571
)
585572
}
586573

587-
#' Override axis text angle and alignment
574+
#' Override text angle and alignment
588575
#'
576+
#' @param element An `element_text()`
589577
#' @param axis_position One of bottom, left, top, or right
590578
#' @param angle The text angle, or NULL to override nothing
591579
#'
592580
#' @return An [element_text()] that contains parameters that should be
593581
#' overridden from the user- or theme-supplied element.
594582
#' @noRd
595-
#'
596-
axis_label_element_overrides <- function(axis_position, angle = NULL) {
597-
598-
if (is.null(angle) || is.waive(angle)) {
599-
return(element_text(angle = NULL, hjust = NULL, vjust = NULL))
583+
label_angle_heuristic <- function(element, position, angle) {
584+
if (!inherits(element, "element_text")
585+
|| is.null(position)
586+
|| is.null(angle %|W|% NULL)) {
587+
return(element)
600588
}
589+
arg_match0(position, .trbl)
601590

602591
check_number_decimal(angle)
603-
angle <- angle %% 360
604-
arg_match0(
605-
axis_position,
606-
c("bottom", "left", "top", "right")
607-
)
608-
609-
if (axis_position == "bottom") {
610-
611-
hjust <- if (angle %in% c(0, 180)) 0.5 else if (angle < 180) 1 else 0
612-
vjust <- if (angle %in% c(90, 270)) 0.5 else if (angle > 90 & angle < 270) 0 else 1
613-
614-
} else if (axis_position == "left") {
615-
616-
hjust <- if (angle %in% c(90, 270)) 0.5 else if (angle > 90 & angle < 270) 0 else 1
617-
vjust <- if (angle %in% c(0, 180)) 0.5 else if (angle < 180) 0 else 1
618-
619-
} else if (axis_position == "top") {
620-
621-
hjust <- if (angle %in% c(0, 180)) 0.5 else if (angle < 180) 0 else 1
622-
vjust <- if (angle %in% c(90, 270)) 0.5 else if (angle > 90 & angle < 270) 1 else 0
623-
624-
} else if (axis_position == "right") {
625-
626-
hjust <- if (angle %in% c(90, 270)) 0.5 else if (angle > 90 & angle < 270) 1 else 0
627-
vjust <- if (angle %in% c(0, 180)) 0.5 else if (angle < 180) 1 else 0
628-
629-
}
630-
631-
element_text(angle = angle, hjust = hjust, vjust = vjust)
592+
radian <- deg2rad(angle)
593+
digits <- 3
594+
595+
# Taking the sign of the (co)sine snaps the value to c(-1, 0, 1)
596+
# Doing `x / 2 + 0.5` rescales it to c(0, 0.5, 1), which are good values for justification
597+
# The rounding step ensures we can get (co)sine to exact 0 so it can become 0.5
598+
# which we need for center-justifications
599+
cosine <- sign(round(cos(radian), digits)) / 2 + 0.5
600+
sine <- sign(round(sin(radian), digits)) / 2 + 0.5
601+
602+
# Depending on position, we might need to swap or flip justification values
603+
hjust <- switch(position, left = cosine, right = 1 - cosine, top = 1 - sine, sine)
604+
vjust <- switch(position, left = 1 - sine, right = sine, top = 1 - cosine, cosine)
605+
606+
element$angle <- angle %||% element$angle
607+
element$hjust <- hjust %||% element$hjust
608+
element$vjust <- vjust %||% element$vjust
609+
element
632610
}

R/guide-bins.R

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ NULL
1111
#' guide if they are mapped in the same way.
1212
#'
1313
#' @inheritParams guide_legend
14+
#' @param angle Overrules the theme settings to automatically apply appropriate
15+
#' `hjust` and `vjust` for angled legend text. Can be a single number
16+
#' representing the text angle in degrees, or `NULL` to not overrule the
17+
#' settings (default).
1418
#' @param show.limits Logical. Should the limits of the scale be shown with
1519
#' labels and ticks. Default is `NULL` meaning it will take the value from the
1620
#' scale. This argument is ignored if `labels` is given as a vector of
@@ -65,6 +69,7 @@ guide_bins <- function(
6569
theme = NULL,
6670

6771
# general
72+
angle = NULL,
6873
position = NULL,
6974
direction = NULL,
7075
override.aes = list(),
@@ -85,6 +90,7 @@ guide_bins <- function(
8590
theme = theme,
8691

8792
# general
93+
angle = angle,
8894
position = position,
8995
direction = direction,
9096
override.aes = rename_aes(override.aes),
@@ -115,6 +121,7 @@ GuideBins <- ggproto(
115121
default_axis = element_line("black", linewidth = (0.5 / .pt)),
116122
default_ticks = element_line(inherit.blank = TRUE),
117123

124+
angle = NULL,
118125
direction = NULL,
119126
override.aes = list(),
120127
reverse = FALSE,

R/guide-colorbar.R

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ NULL
3232
#' @param alpha A numeric between 0 and 1 setting the colour transparency of
3333
#' the bar. Use `NA` to preserve the alpha encoded in the colour itself
3434
#' (default).
35+
#' @param angle Overrules the theme settings to automatically apply appropriate
36+
#' `hjust` and `vjust` for angled legend text. Can be a single number
37+
#' representing the text angle in degrees, or `NULL` to not overrule the
38+
#' settings (default).
3539
#' @param draw.ulim A logical specifying if the upper limit tick marks should
3640
#' be visible.
3741
#' @param draw.llim A logical specifying if the lower limit tick marks should
@@ -124,6 +128,7 @@ guide_colourbar <- function(
124128
alpha = NA,
125129
draw.ulim = TRUE,
126130
draw.llim = TRUE,
131+
angle = NULL,
127132
position = NULL,
128133
direction = NULL,
129134
reverse = FALSE,
@@ -151,6 +156,7 @@ guide_colourbar <- function(
151156
nbin = nbin,
152157
display = display,
153158
alpha = alpha,
159+
angle = angle,
154160
draw_lim = c(isTRUE(draw.llim), isTRUE(draw.ulim)),
155161
position = position,
156162
direction = direction,
@@ -193,6 +199,7 @@ GuideColourbar <- ggproto(
193199
direction = NULL,
194200
reverse = FALSE,
195201
order = 0,
202+
angle = NULL,
196203

197204
# parameter
198205
name = "colourbar",

R/guide-colorsteps.R

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ guide_coloursteps <- function(
4949
title = waiver(),
5050
theme = NULL,
5151
alpha = NA,
52+
angle = NULL,
5253
even.steps = TRUE,
5354
show.limits = NULL,
5455
direction = NULL,
@@ -66,6 +67,7 @@ guide_coloursteps <- function(
6667
title = title,
6768
theme = theme,
6869
alpha = alpha,
70+
angle = angle,
6971
even.steps = even.steps,
7072
show.limits = show.limits,
7173
position = position,

R/guide-legend.R

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,9 @@ GuideLegend <- ggproto(
374374
ggname("legend.key", element_grob(elements$key))
375375
}
376376

377+
elements$text <-
378+
label_angle_heuristic(elements$text, elements$text_position, params$angle)
379+
377380
elements
378381
},
379382

man/guide_bins.Rd

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/guide_colourbar.Rd

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/guide_coloursteps.Rd

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/_snaps/coord_sf/coord-sf-with-custom-guides.svg

Lines changed: 21 additions & 21 deletions
Loading

0 commit comments

Comments
 (0)