Skip to content

Commit 047b528

Browse files
authored
Make plot title position configurable. (#3494)
* add plot.title.position theme element * add plot.title.position to all themes, add visual test. * Make separate parameter for caption position. Closes #3252.
1 parent 49d438c commit 047b528

File tree

10 files changed

+687
-10
lines changed

10 files changed

+687
-10
lines changed

NEWS.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@
2121

2222
* Changed `theme_grey()` setting for legend key so that it creates no
2323
border (`NA`) rather than drawing a white one. (@annennenne, #3180)
24+
25+
* Themes have gained two new parameters, `plot.title.position` and
26+
`plot.caption.position`, that can be used to customize how plot
27+
title/subtitle and plot caption are positioned relative to the overall plot
28+
(@clauswilke, #3252).
2429

2530
* Added function `ggplot_add.by()` for lists created with `by()` (#2734, @Maschette)
2631

R/plot-build.r

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -261,20 +261,46 @@ ggplot_gtable.ggplot_built <- function(data) {
261261
caption <- element_render(theme, "plot.caption", plot$labels$caption, margin_y = TRUE)
262262
caption_height <- grobHeight(caption)
263263

264-
pans <- plot_table$layout[grepl("^panel", plot_table$layout$name), ,
265-
drop = FALSE]
264+
# positioning of title and subtitle is governed by plot.title.position
265+
# positioning of caption is governed by plot.caption.position
266+
# "panel" means align to the panel(s)
267+
# "plot" means align to the entire plot (except margins and tag)
268+
title_pos <- theme$plot.title.position %||% "panel"
269+
if (!(title_pos %in% c("panel", "plot"))) {
270+
stop('plot.title.position should be either "panel" or "plot".', call. = FALSE)
271+
}
272+
caption_pos <- theme$plot.caption.position %||% "panel"
273+
if (!(caption_pos %in% c("panel", "plot"))) {
274+
stop('plot.caption.position should be either "panel" or "plot".', call. = FALSE)
275+
}
276+
277+
pans <- plot_table$layout[grepl("^panel", plot_table$layout$name), , drop = FALSE]
278+
if (title_pos == "panel") {
279+
title_l = min(pans$l)
280+
title_r = max(pans$r)
281+
} else {
282+
title_l = 1
283+
title_r = ncol(plot_table)
284+
}
285+
if (caption_pos == "panel") {
286+
caption_l = min(pans$l)
287+
caption_r = max(pans$r)
288+
} else {
289+
caption_l = 1
290+
caption_r = ncol(plot_table)
291+
}
266292

267293
plot_table <- gtable_add_rows(plot_table, subtitle_height, pos = 0)
268294
plot_table <- gtable_add_grob(plot_table, subtitle, name = "subtitle",
269-
t = 1, b = 1, l = min(pans$l), r = max(pans$r), clip = "off")
295+
t = 1, b = 1, l = title_l, r = title_r, clip = "off")
270296

271297
plot_table <- gtable_add_rows(plot_table, title_height, pos = 0)
272298
plot_table <- gtable_add_grob(plot_table, title, name = "title",
273-
t = 1, b = 1, l = min(pans$l), r = max(pans$r), clip = "off")
299+
t = 1, b = 1, l = title_l, r = title_r, clip = "off")
274300

275301
plot_table <- gtable_add_rows(plot_table, caption_height, pos = -1)
276302
plot_table <- gtable_add_grob(plot_table, caption, name = "caption",
277-
t = -1, b = -1, l = min(pans$l), r = max(pans$r), clip = "off")
303+
t = -1, b = -1, l = caption_l, r = caption_r, clip = "off")
278304

279305
plot_table <- gtable_add_rows(plot_table, unit(0, 'pt'), pos = 0)
280306
plot_table <- gtable_add_cols(plot_table, unit(0, 'pt'), pos = 0)

R/theme-defaults.r

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ theme_grey <- function(base_size = 11, base_family = "",
214214
hjust = 0, vjust = 1,
215215
margin = margin(b = half_line)
216216
),
217+
plot.title.position = "panel",
217218
plot.subtitle = element_text( # font size "regular"
218219
hjust = 0, vjust = 1,
219220
margin = margin(b = half_line)
@@ -223,6 +224,7 @@ theme_grey <- function(base_size = 11, base_family = "",
223224
hjust = 1, vjust = 1,
224225
margin = margin(t = half_line)
225226
),
227+
plot.caption.position = "panel",
226228
plot.tag = element_text(
227229
size = rel(1.2),
228230
hjust = 0.5, vjust = 0.5
@@ -487,6 +489,7 @@ theme_void <- function(base_size = 11, base_family = "",
487489
hjust = 0, vjust = 1,
488490
margin = margin(t = half_line)
489491
),
492+
plot.title.position = "panel",
490493
plot.subtitle = element_text(
491494
hjust = 0, vjust = 1,
492495
margin = margin(t = half_line)
@@ -496,6 +499,7 @@ theme_void <- function(base_size = 11, base_family = "",
496499
hjust = 1, vjust = 1,
497500
margin = margin(t = half_line)
498501
),
502+
plot.caption.position = "panel",
499503
plot.tag = element_text(
500504
size = rel(1.2),
501505
hjust = 0.5, vjust = 0.5
@@ -615,6 +619,7 @@ theme_test <- function(base_size = 11, base_family = "",
615619
hjust = 0, vjust = 1,
616620
margin = margin(b = half_line)
617621
),
622+
plot.title.position = "panel",
618623
plot.subtitle = element_text(
619624
hjust = 0, vjust = 1,
620625
margin = margin(b = half_line)
@@ -624,6 +629,7 @@ theme_test <- function(base_size = 11, base_family = "",
624629
hjust = 1, vjust = 1,
625630
margin = margin(t = half_line)
626631
),
632+
plot.caption.position = "panel",
627633
plot.tag = element_text(
628634
size = rel(1.2),
629635
hjust = 0.5, vjust = 0.5

R/theme-elements.r

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,8 +370,10 @@ el_def <- function(class = NULL, inherit = NULL, description = NULL) {
370370

371371
plot.background = el_def("element_rect", "rect"),
372372
plot.title = el_def("element_text", "title"),
373+
plot.title.position = el_def("character"),
373374
plot.subtitle = el_def("element_text", "title"),
374375
plot.caption = el_def("element_text", "title"),
376+
plot.caption.position = el_def("character"),
375377
plot.tag = el_def("element_text", "title"),
376378
plot.tag.position = el_def("character"), # Need to also accept numbers
377379
plot.margin = el_def("margin"),

R/theme.r

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,12 @@
124124
#' inherits from `title`) left-aligned by default
125125
#' @param plot.caption caption below the plot (text appearance)
126126
#' ([element_text()]; inherits from `title`) right-aligned by default
127+
#' @param plot.title.position,plot.caption.position Alignment of the plot title/subtitle
128+
#' and caption. The setting for `plot.title.position` applies to both
129+
#' the title and the subtitle. A value of "panel" (the default) means that
130+
#' titles and/or caption are aligned to the plot panels. A value of "plot" means
131+
#' that titles and/or caption are aligned to the entire plot (minus any space
132+
#' for margins and plot tag).
127133
#' @param plot.tag upper-left label to identify a plot (text appearance)
128134
#' ([element_text()]; inherits from `title`) left-aligned by default
129135
#' @param plot.tag.position The position of the tag as a string ("topleft",
@@ -334,8 +340,10 @@ theme <- function(line,
334340
panel.ontop,
335341
plot.background,
336342
plot.title,
343+
plot.title.position,
337344
plot.subtitle,
338345
plot.caption,
346+
plot.caption.position,
339347
plot.tag,
340348
plot.tag.position,
341349
plot.margin,

man/theme.Rd

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

0 commit comments

Comments
 (0)