Skip to content

Commit 4c5bb24

Browse files
authored
Partial margins (#6116)
* inheritance of NA-margins * add `part_margin()` function * setup merge method for margins * add test * add news bullet * rename `part_margin()` to `margin_part()` * rename `part_margin()` to `margin_part()` * new `margin_auto()` * use `margin_auto()` where appropriate * fix mistake in issue id
1 parent 73f6bff commit 4c5bb24

13 files changed

+91
-21
lines changed

NAMESPACE

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ S3method(makeContext,dotstackGrob)
9494
S3method(merge_element,default)
9595
S3method(merge_element,element)
9696
S3method(merge_element,element_blank)
97+
S3method(merge_element,margin)
9798
S3method(pattern_alpha,GridPattern)
9899
S3method(pattern_alpha,GridTilingPattern)
99100
S3method(pattern_alpha,default)
@@ -494,6 +495,8 @@ export(layer_sf)
494495
export(lims)
495496
export(map_data)
496497
export(margin)
498+
export(margin_auto)
499+
export(margin_part)
497500
export(max_height)
498501
export(max_width)
499502
export(mean_cl_boot)

NEWS.md

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

3+
* Theme margins can have NA-units to inherit from parent elements. The new
4+
function `margin_part()` has NA-units as default (@teunbrand, #6115)
5+
* New `margin_auto()` specification for theme margins.
36
* New argument `labs(dictionary)` to label based on variable name rather than
47
based on aesthetic (@teunbrand, #5178)
58
* Fixed bug in out-of-bounds binned breaks (@teunbrand, #6054)

R/geom-rug.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
#' p +
4646
#' geom_rug(outside = TRUE, sides = "tr") +
4747
#' coord_cartesian(clip = "off") +
48-
#' theme(plot.margin = margin(1, 1, 1, 1, "cm"))
48+
#' theme(plot.margin = margin_auto(1, unit = "cm"))
4949
#'
5050
#' # increase the line length and
5151
#' # expand axis to avoid overplotting

R/legend-draw.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ draw_key_text <- function(data, params, size) {
320320
fontface = data$fontface %||% 1,
321321
fontsize = (data$size %||% 3.88) * .pt
322322
),
323-
margin = margin(0.1, 0.1, 0.1, 0.1, unit = "lines"),
323+
margin = margin_auto(0.1, unit = "lines"),
324324
margin_x = TRUE, margin_y = TRUE
325325
)
326326
attr(grob, "width") <- convertWidth(grobWidth(grob), "cm", valueOnly = TRUE)

R/margins.R

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,18 @@ margin <- function(t = 0, r = 0, b = 0, l = 0, unit = "pt") {
99
u
1010
}
1111

12+
#' @rdname element
13+
#' @export
14+
margin_part <- function(t = NA, r = NA, b = NA, l = NA, unit = "pt") {
15+
margin(t = t, r = r, b = b, l = l, unit = unit)
16+
}
17+
18+
#' @rdname element
19+
#' @export
20+
margin_auto <- function(t = 0, r = t, b = t, l = r, unit = "pt") {
21+
margin(t = t, r = r, b = b, l = l, unit)
22+
}
23+
1224
#' @export
1325
#' @rdname is_tests
1426
is.margin <- function(x) inherits(x, "margin")

R/theme-defaults.R

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ theme_grey <- function(base_size = 11, base_family = "",
143143
title = element_text(family = header_family),
144144

145145
spacing = unit(half_line, "pt"),
146-
margins = margin(half_line, half_line, half_line, half_line),
146+
margins = margin_auto(half_line),
147147

148148
geom = element_geom(
149149
ink = ink, paper = paper, accent = "#3366FF",
@@ -226,7 +226,7 @@ theme_grey <- function(base_size = 11, base_family = "",
226226
strip.text = element_text(
227227
colour = col_mix(ink, paper, 0.105),
228228
size = rel(0.8),
229-
margin = margin(0.8 * half_line, 0.8 * half_line, 0.8 * half_line, 0.8 * half_line)
229+
margin = margin_auto(0.8 * half_line)
230230
),
231231
strip.text.x = NULL,
232232
strip.text.y = element_text(angle = -90),
@@ -341,7 +341,7 @@ theme_linedraw <- function(base_size = 11, base_family = "",
341341
strip.text = element_text(
342342
colour = paper,
343343
size = rel(0.8),
344-
margin = margin(0.8 * half_line, 0.8 * half_line, 0.8 * half_line, 0.8 * half_line)
344+
margin = margin_auto(0.8 * half_line)
345345
),
346346

347347
complete = TRUE
@@ -384,7 +384,7 @@ theme_light <- function(base_size = 11, base_family = "",
384384
strip.text = element_text(
385385
colour = paper,
386386
size = rel(0.8),
387-
margin = margin(0.8 * half_line, 0.8 * half_line, 0.8 * half_line, 0.8 * half_line)
387+
margin = margin_auto(0.8 * half_line)
388388
),
389389

390390
complete = TRUE
@@ -427,7 +427,7 @@ theme_dark <- function(base_size = 11, base_family = "",
427427
strip.text = element_text(
428428
colour = col_mix(ink, paper, 0.9),
429429
size = rel(0.8),
430-
margin = margin(0.8 * half_line, 0.8 * half_line, 0.8 * half_line, 0.8 * half_line)
430+
margin = margin_auto(0.8 * half_line)
431431
),
432432

433433
complete = TRUE
@@ -557,7 +557,7 @@ theme_void <- function(base_size = 11, base_family = "",
557557
),
558558
title = element_text(family = header_family),
559559
spacing = unit(half_line, "pt"),
560-
margins = margin(half_line, half_line, half_line, half_line),
560+
margins = margin_auto(half_line),
561561
axis.text = element_blank(),
562562
axis.title = element_blank(),
563563
axis.ticks.length = rel(0),
@@ -641,7 +641,7 @@ theme_test <- function(base_size = 11, base_family = "",
641641
),
642642
title = element_text(family = header_family),
643643
spacing = unit(half_line, "pt"),
644-
margins = margin(half_line, half_line, half_line, half_line),
644+
margins = margin_auto(half_line),
645645
geom = element_geom(
646646
ink = ink, paper = paper, accent = "#3366FF",
647647
linewidth = base_line_size, borderwidth = base_line_size,
@@ -690,7 +690,7 @@ theme_test <- function(base_size = 11, base_family = "",
690690
legend.spacing = rel(2),
691691
legend.spacing.x = NULL,
692692
legend.spacing.y = NULL,
693-
legend.margin = margin(0, 0, 0, 0, "cm"),
693+
legend.margin = margin_auto(0, unit = "cm"),
694694
legend.key = NULL,
695695
legend.key.size = unit(1.2, "lines"),
696696
legend.key.height = NULL,
@@ -705,7 +705,7 @@ theme_test <- function(base_size = 11, base_family = "",
705705
legend.direction = NULL,
706706
legend.justification = "center",
707707
legend.box = NULL,
708-
legend.box.margin = margin(0, 0, 0, 0, "cm"),
708+
legend.box.margin = margin_auto(0, unit = "cm"),
709709
legend.box.background = element_blank(),
710710
legend.box.spacing = rel(2),
711711

@@ -726,7 +726,7 @@ theme_test <- function(base_size = 11, base_family = "",
726726
strip.text = element_text(
727727
colour = col_mix(ink, paper, 0.105),
728728
size = rel(0.8),
729-
margin = margin(0.8 * half_line, 0.8 * half_line, 0.8 * half_line, 0.8 * half_line)
729+
margin = margin_auto(0.8 * half_line)
730730
),
731731
strip.text.x = NULL,
732732
strip.text.y = element_text(angle = -90),

R/theme-elements.R

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
#' - `element_geom()`: defaults for drawing layers.
1212
#'
1313
#' `rel()` is used to specify sizes relative to the parent,
14-
#' `margin()` is used to specify the margins of elements.
14+
#' `margin()`, `margin_part()` and `margin_auto()` are all used to specify the
15+
#' margins of elements.
1516
#'
1617
#' @param fill Fill colour.
1718
#' @param colour,color Line/border colour. Color is an alias for colour.
@@ -42,7 +43,7 @@
4243
#'
4344
#' plot + theme(
4445
#' panel.background = element_rect(fill = "white"),
45-
#' plot.margin = margin(2, 2, 2, 2, "cm"),
46+
#' plot.margin = margin_auto(2, unit = "cm"),
4647
#' plot.background = element_rect(
4748
#' fill = "grey90",
4849
#' colour = "black",

R/theme.R

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -281,14 +281,14 @@
281281
#' legend.position.inside = c(.95, .95),
282282
#' legend.justification = c("right", "top"),
283283
#' legend.box.just = "right",
284-
#' legend.margin = margin(6, 6, 6, 6)
284+
#' legend.margin = margin_auto(6)
285285
#' )
286286
#'
287287
#' # The legend.box properties work similarly for the space around
288288
#' # all the legends
289289
#' p2 + theme(
290290
#' legend.box.background = element_rect(),
291-
#' legend.box.margin = margin(6, 6, 6, 6)
291+
#' legend.box.margin = margin_auto(6)
292292
#' )
293293
#'
294294
#' # You can also control the display of the keys
@@ -835,6 +835,18 @@ merge_element.element <- function(new, old) {
835835
new
836836
}
837837

838+
#' @rdname merge_element
839+
#' @export
840+
merge_element.margin <- function(new, old) {
841+
if (is.null(old) || inherits(old, "element_blank")) {
842+
return(new)
843+
}
844+
if (anyNA(new)) {
845+
new[is.na(new)] <- old[is.na(new)]
846+
}
847+
new
848+
}
849+
838850
#' Combine the properties of two elements
839851
#'
840852
#' @param e1 An element object
@@ -868,6 +880,15 @@ combine_elements <- function(e1, e2) {
868880
return(e1)
869881
}
870882

883+
if (inherits(e1, "margin") && inherits(e2, "margin")) {
884+
if (anyNA(e2)) {
885+
e2[is.na(e2)] <- unit(0, "pt")
886+
}
887+
if (anyNA(e1)) {
888+
e1[is.na(e1)] <- e2[is.na(e1)]
889+
}
890+
}
891+
871892
# If neither of e1 or e2 are element_* objects, return e1
872893
if (!inherits(e1, "element") && !inherits(e2, "element")) {
873894
return(e1)
@@ -897,6 +918,10 @@ combine_elements <- function(e1, e2) {
897918
e1$linewidth <- e2$linewidth * unclass(e1$linewidth)
898919
}
899920

921+
if (inherits(e1, "element_text")) {
922+
e1$margin <- combine_elements(e1$margin, e2$margin)
923+
}
924+
900925
# If e2 is 'richer' than e1, fill e2 with e1 parameters
901926
is_subclass <- !any(inherits(e2, class(e1), which = TRUE) == 0)
902927
is_subclass <- is_subclass && length(setdiff(class(e2), class(e1)) > 0)

man/element.Rd

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

man/geom_rug.Rd

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/merge_element.Rd

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

man/theme.Rd

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

tests/testthat/test-theme.R

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,22 @@ test_that("complete_theme completes a theme", {
617617
reset_theme_settings()
618618
})
619619

620+
test_that("margin_part() mechanics work as expected", {
621+
622+
t <- theme_gray() +
623+
theme(plot.margin = margin_part(b = 11))
624+
625+
test <- calc_element("plot.margin", t)
626+
expect_equal(as.numeric(test), c(5.5, 5.5, 11, 5.5))
627+
628+
t <- theme_gray() +
629+
theme(margins = margin_part(b = 11))
630+
631+
test <- calc_element("plot.margin", t)
632+
expect_equal(as.numeric(test), c(5.5, 5.5, 11, 5.5))
633+
634+
})
635+
620636
# Visual tests ------------------------------------------------------------
621637

622638
test_that("aspect ratio is honored", {

0 commit comments

Comments
 (0)