From fcf9081d2bf0ac14defdd0e3092b60e013bbb111 Mon Sep 17 00:00:00 2001 From: thomasp85 Date: Fri, 16 Sep 2016 10:38:22 +0200 Subject: [PATCH 1/9] Add inherit.blank argument to element constructors --- R/theme-elements.r | 15 +++++++++------ man/element.Rd | 9 ++++++--- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/R/theme-elements.r b/R/theme-elements.r index e6527d552..a474be7aa 100644 --- a/R/theme-elements.r +++ b/R/theme-elements.r @@ -13,6 +13,8 @@ #' @param fill Fill colour. #' @param colour,color Line/border colour. Color is an alias for colour. #' @param size Line/border size in mm; text size in pts. +#' @param inherit.blank Should this element inherit the existence of an +#' element_blank among its parents? #' @name element #' @return An S3 object of class \code{element}. #' @examples @@ -49,11 +51,12 @@ element_blank <- function() { #' @export #' @rdname element element_rect <- function(fill = NULL, colour = NULL, size = NULL, - linetype = NULL, color = NULL) { + linetype = NULL, color = NULL, inherit.blank = FALSE) { if (!is.null(color)) colour <- color structure( - list(fill = fill, colour = colour, size = size, linetype = linetype), + list(fill = fill, colour = colour, size = size, linetype = linetype, + inherit.blank = inherit.blank), class = c("element_rect", "element") ) } @@ -67,13 +70,13 @@ element_rect <- function(fill = NULL, colour = NULL, size = NULL, #' @param lineend Line end Line end style (round, butt, square) #' @param arrow Arrow specification, as created by \code{\link[grid]{arrow}} element_line <- function(colour = NULL, size = NULL, linetype = NULL, - lineend = NULL, color = NULL, arrow = NULL) { + lineend = NULL, color = NULL, arrow = NULL, inherit.blank = FALSE) { if (!is.null(color)) colour <- color if (is.null(arrow)) arrow <- FALSE structure( list(colour = colour, size = size, linetype = linetype, lineend = lineend, - arrow = arrow), + arrow = arrow, inherit.blank = inherit.blank), class = c("element_line", "element") ) } @@ -95,13 +98,13 @@ element_line <- function(colour = NULL, size = NULL, linetype = NULL, #' @rdname element element_text <- function(family = NULL, face = NULL, colour = NULL, size = NULL, hjust = NULL, vjust = NULL, angle = NULL, lineheight = NULL, - color = NULL, margin = NULL, debug = NULL) { + color = NULL, margin = NULL, debug = NULL, inherit.blank = FALSE) { if (!is.null(color)) colour <- color structure( list(family = family, face = face, colour = colour, size = size, hjust = hjust, vjust = vjust, angle = angle, lineheight = lineheight, - margin = margin, debug = debug), + margin = margin, debug = debug, inherit.blank = inherit.blank), class = c("element_text", "element") ) } diff --git a/man/element.Rd b/man/element.Rd index bb39c65a2..f41409199 100644 --- a/man/element.Rd +++ b/man/element.Rd @@ -11,14 +11,14 @@ element_blank() element_rect(fill = NULL, colour = NULL, size = NULL, linetype = NULL, - color = NULL) + color = NULL, inherit.blank = FALSE) element_line(colour = NULL, size = NULL, linetype = NULL, - lineend = NULL, color = NULL, arrow = NULL) + lineend = NULL, color = NULL, arrow = NULL, inherit.blank = FALSE) element_text(family = NULL, face = NULL, colour = NULL, size = NULL, hjust = NULL, vjust = NULL, angle = NULL, lineheight = NULL, - color = NULL, margin = NULL, debug = NULL) + color = NULL, margin = NULL, debug = NULL, inherit.blank = FALSE) } \arguments{ \item{fill}{Fill colour.} @@ -32,6 +32,9 @@ dashed, dotted, dotdash, longdash, twodash), or a string with an even number (up to eight) of hexadecimal digits which give the lengths in consecutive positions in the string.} +\item{inherit.blank}{Should this element inherit the existence of an +element_blank among its parents?} + \item{lineend}{Line end Line end style (round, butt, square)} \item{arrow}{Arrow specification, as created by \code{\link[grid]{arrow}}} From 37deef56e33a71d885adeda3d69a71d3ec03635d Mon Sep 17 00:00:00 2001 From: thomasp85 Date: Fri, 16 Sep 2016 13:33:43 +0200 Subject: [PATCH 2/9] Look for inherit.blank when combining --- R/theme.r | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/R/theme.r b/R/theme.r index d95c7568c..15aee36d7 100644 --- a/R/theme.r +++ b/R/theme.r @@ -633,10 +633,14 @@ calc_element <- function(element, theme, verbose = FALSE) { combine_elements <- function(e1, e2) { # If e2 is NULL, nothing to inherit - if (is.null(e2)) return(e1) - + if (is.null(e2) || inherits(e1, "element_blank")) return(e1) + # If e1 is NULL inherit everything from e2 + if (is.null(e1)) return(e2) # If e1 is NULL, or if e2 is element_blank, inherit everything from e2 - if (is.null(e1) || inherits(e2, "element_blank")) return(e2) + if (inherits(e2, "element_blank")) { + if (e1$inherit.blank) return(e2) + else return(e1) + } # If e1 has any NULL properties, inherit them from e2 n <- vapply(e1[names(e2)], is.null, logical(1)) From 3b27d0f21f30034fd3e21a892f1fcc857e5c6126 Mon Sep 17 00:00:00 2001 From: thomasp85 Date: Fri, 16 Sep 2016 13:33:59 +0200 Subject: [PATCH 3/9] Update default themes for the new setup --- R/theme-defaults.r | 129 ++++++++++++++++++++++++++--------------------------- 1 file changed, 64 insertions(+), 65 deletions(-) diff --git a/R/theme-defaults.r b/R/theme-defaults.r index 3dc5d8f4e..cb175af5b 100644 --- a/R/theme-defaults.r +++ b/R/theme-defaults.r @@ -76,36 +76,36 @@ theme_grey <- function(base_size = 11, base_family = "") { margin = margin(), debug = FALSE ), - axis.line = element_line(), - axis.line.x = element_blank(), - axis.line.y = element_blank(), - axis.text = element_text(size = rel(0.8), colour = "grey30"), - axis.text.x = element_text(margin = margin(t = 0.8 * half_line / 2), vjust = 1), - axis.text.y = element_text(margin = margin(r = 0.8 * half_line / 2), hjust = 1), - axis.ticks = element_line(colour = "grey20"), + axis.line = element_blank(), + axis.line.x = NULL, + axis.line.y = NULL, + axis.text = element_text(size = rel(0.8), colour = "grey30", inherit.blank = TRUE), + axis.text.x = element_text(margin = margin(t = 0.8 * half_line / 2), vjust = 1, inherit.blank = TRUE), + axis.text.y = element_text(margin = margin(r = 0.8 * half_line / 2), hjust = 1, inherit.blank = TRUE), + axis.ticks = element_line(colour = "grey20", inherit.blank = TRUE), axis.ticks.length = unit(half_line / 2, "pt"), axis.title.x = element_text( margin = margin(t = half_line), - vjust = 1 + vjust = 1, inherit.blank = TRUE ), axis.title.y = element_text( angle = 90, margin = margin(r = half_line), - vjust = 1, + vjust = 1, inherit.blank = TRUE ), - legend.background = element_rect(colour = NA), + legend.background = element_rect(colour = NA, inherit.blank = TRUE), legend.spacing = unit(0.4, "cm"), legend.spacing.x = NULL, legend.spacing.y = NULL, legend.margin = margin(0, 0, 0, 0, "cm"), - legend.key = element_rect(fill = "grey95", colour = "white"), + legend.key = element_rect(fill = "grey95", colour = "white", inherit.blank = TRUE), legend.key.size = unit(1.2, "lines"), legend.key.height = NULL, legend.key.width = NULL, - legend.text = element_text(size = rel(0.8)), + legend.text = element_text(size = rel(0.8), inherit.blank = TRUE), legend.text.align = NULL, - legend.title = element_text(hjust = 0), + legend.title = element_text(hjust = 0, inherit.blank = TRUE), legend.title.align = NULL, legend.position = "right", legend.direction = NULL, @@ -115,37 +115,40 @@ theme_grey <- function(base_size = 11, base_family = "") { legend.box.background = element_blank(), legend.box.spacing = unit(0.4, "cm"), - panel.background = element_rect(fill = "grey92", colour = NA), + panel.background = element_rect(fill = "grey92", colour = NA, inherit.blank = TRUE), panel.border = element_blank(), - panel.grid.major = element_line(colour = "white"), - panel.grid.minor = element_line(colour = "white", size = 0.25), + panel.grid.major = element_line(colour = "white", inherit.blank = TRUE), + panel.grid.minor = element_line(colour = "white", size = 0.25, inherit.blank = TRUE), panel.spacing = unit(half_line, "pt"), panel.spacing.x = NULL, panel.spacing.y = NULL, panel.ontop = FALSE, - strip.background = element_rect(fill = "grey85", colour = NA), - strip.text = element_text(colour = "grey10", size = rel(0.8)), - strip.text.x = element_text(margin = margin(t = half_line, b = half_line)), - strip.text.y = element_text(angle = -90, margin = margin(l = half_line, r = half_line)), + strip.background = element_rect(fill = "grey85", colour = NA, inherit.blank = TRUE), + strip.text = element_text(colour = "grey10", size = rel(0.8), inherit.blank = TRUE), + strip.text.x = element_text(margin = margin(t = half_line, b = half_line), inherit.blank = TRUE), + strip.text.y = element_text(angle = -90, margin = margin(l = half_line, r = half_line), inherit.blank = TRUE), strip.switch.pad.grid = unit(0.1, "cm"), strip.switch.pad.wrap = unit(0.1, "cm"), - plot.background = element_rect(colour = "white"), + plot.background = element_rect(colour = "white", inherit.blank = TRUE), plot.title = element_text( size = rel(1.2), hjust = 0, vjust = 1, - margin = margin(b = half_line * 1.2) + margin = margin(b = half_line * 1.2), + inherit.blank = TRUE ), plot.subtitle = element_text( size = rel(0.9), hjust = 0, vjust = 1, - margin = margin(b = half_line * 0.9) + margin = margin(b = half_line * 0.9), + inherit.blank = TRUE ), plot.caption = element_text( size = rel(0.9), hjust = 1, vjust = 1, - margin = margin(t = half_line * 0.9) + margin = margin(t = half_line * 0.9), + inherit.blank = TRUE ), plot.margin = margin(half_line, half_line, half_line, half_line), @@ -163,15 +166,15 @@ theme_bw <- function(base_size = 11, base_family = "") { theme_grey(base_size = base_size, base_family = base_family) %+replace% theme( # white background and dark border - panel.background = element_rect(fill = "white", colour = NA), - panel.border = element_rect(fill = NA, colour = "grey20"), + panel.background = element_rect(fill = "white", colour = NA, inherit.blank = TRUE), + panel.border = element_rect(fill = NA, colour = "grey20", inherit.blank = TRUE), # make gridlines dark, same contrast with white as in theme_grey - panel.grid.major = element_line(colour = "grey92"), - panel.grid.minor = element_line(colour = "grey92", size = 0.25), + panel.grid.major = element_line(colour = "grey92", inherit.blank = TRUE), + panel.grid.minor = element_line(colour = "grey92", size = 0.25, inherit.blank = TRUE), # contour strips to match panel contour - strip.background = element_rect(fill = "grey85", colour = "grey20"), + strip.background = element_rect(fill = "grey85", colour = "grey20", inherit.blank = TRUE), # match legend key to background - legend.key = element_rect(fill = "white", colour=NA) + legend.key = element_rect(fill = "white", colour=NA, inherit.blank = TRUE) ) } @@ -183,19 +186,19 @@ theme_linedraw <- function(base_size = 11, base_family = "") { theme_bw(base_size = base_size, base_family = base_family) %+replace% theme( # black text and ticks on the axes - axis.text = element_text(colour = "black", size = rel(0.8)), - axis.ticks = element_line(colour = "black", size = 0.25), + axis.text = element_text(colour = "black", size = rel(0.8), inherit.blank = TRUE), + axis.ticks = element_line(colour = "black", size = 0.25, inherit.blank = TRUE), # NB: match the *visual* thickness of axis ticks to the panel border # 0.5 clipped looks like 0.25 # pure black panel border and grid lines, but thinner - panel.border = element_rect(fill = NA, colour = "black", size = 0.5), - panel.grid.major = element_line(colour = "black", size = 0.05), - panel.grid.minor = element_line(colour = "black", size = 0.025), + panel.border = element_rect(fill = NA, colour = "black", size = 0.5, inherit.blank = TRUE), + panel.grid.major = element_line(colour = "black", size = 0.05, inherit.blank = TRUE), + panel.grid.minor = element_line(colour = "black", size = 0.025, inherit.blank = TRUE), # strips with black background and white text - strip.background = element_rect(fill = "black"), - strip.text = element_text(colour = "white", size = rel(0.8)) + strip.background = element_rect(fill = "black", inherit.blank = TRUE), + strip.text = element_text(colour = "white", size = rel(0.8), inherit.blank = TRUE) ) } @@ -206,22 +209,22 @@ theme_light <- function(base_size = 11, base_family = "") { theme_grey(base_size = base_size, base_family = base_family) %+replace% theme( # white panel with light grey border - panel.background = element_rect(fill = "white", colour = NA), - panel.border = element_rect(fill = NA, colour = "grey70", size = 0.5), + panel.background = element_rect(fill = "white", colour = NA, inherit.blank = TRUE), + panel.border = element_rect(fill = NA, colour = "grey70", size = 0.5, inherit.blank = TRUE), # light grey, thinner gridlines # => make them slightly darker to keep acceptable contrast - panel.grid.major = element_line(colour = "grey87", size = 0.25), - panel.grid.minor = element_line(colour = "grey87", size = 0.125), + panel.grid.major = element_line(colour = "grey87", size = 0.25, inherit.blank = TRUE), + panel.grid.minor = element_line(colour = "grey87", size = 0.125, inherit.blank = TRUE), # match axes ticks thickness to gridlines and colour to panel border - axis.ticks = element_line(colour = "grey70", size = 0.25), + axis.ticks = element_line(colour = "grey70", size = 0.25, inherit.blank = TRUE), # match legend key to panel.background - legend.key = element_rect(fill = "white", colour = NA), + legend.key = element_rect(fill = "white", colour = NA, inherit.blank = TRUE), # dark strips with light text (inverse contrast compared to theme_grey) - strip.background = element_rect(fill = "grey70", colour = NA), - strip.text = element_text(colour = "white", size = rel(0.8)) + strip.background = element_rect(fill = "grey70", colour = NA, inherit.blank = TRUE), + strip.text = element_text(colour = "white", size = rel(0.8), inherit.blank = TRUE) ) } @@ -233,21 +236,21 @@ theme_dark <- function(base_size = 11, base_family = "") { theme_grey(base_size = base_size, base_family = base_family) %+replace% theme( # dark panel - panel.background = element_rect(fill = "grey50", colour = NA), + panel.background = element_rect(fill = "grey50", colour = NA, inherit.blank = TRUE), # inverse grid lines contrast compared to theme_grey # make them thinner and try to keep the same visual contrast as in theme_light - panel.grid.major = element_line(colour = "grey42", size = 0.25), - panel.grid.minor = element_line(colour = "grey42", size = 0.125), + panel.grid.major = element_line(colour = "grey42", size = 0.25, inherit.blank = TRUE), + panel.grid.minor = element_line(colour = "grey42", size = 0.125, inherit.blank = TRUE), # match axes ticks thickness to gridlines - axis.ticks = element_line(colour = "grey20", size = 0.25), + axis.ticks = element_line(colour = "grey20", size = 0.25, inherit.blank = TRUE), # match legend key to panel.background - legend.key = element_rect(fill = "grey50", colour = NA), + legend.key = element_rect(fill = "grey50", colour = NA, inherit.blank = TRUE), # dark strips with light text (inverse contrast compared to theme_grey) - strip.background = element_rect(fill = "grey15", colour = NA), - strip.text = element_text(colour = "grey90", size = rel(0.8)) + strip.background = element_rect(fill = "grey15", colour = NA, inherit.blank = TRUE), + strip.text = element_text(colour = "grey90", size = rel(0.8), inherit.blank = TRUE) ) } @@ -257,8 +260,7 @@ theme_minimal <- function(base_size = 11, base_family = "") { # Starts with theme_bw and remove most parts theme_bw(base_size = base_size, base_family = base_family) %+replace% theme( - axis.ticks.x = element_blank(), - axis.ticks.y = element_blank(), + axis.ticks = element_blank(), legend.background = element_blank(), legend.key = element_blank(), panel.background = element_blank(), @@ -279,14 +281,13 @@ theme_classic <- function(base_size = 11, base_family = ""){ panel.grid.minor = element_blank(), # show axes - axis.line.x = element_line(colour = "black", size = 0.5), - axis.line.y = element_line(colour = "black", size = 0.5), + axis.line = element_line(colour = "black", size = 0.5, inherit.blank = TRUE), # match legend key to panel.background legend.key = element_blank(), # simple, black and white strips - strip.background = element_rect(fill = "white", colour = "black", size = 1) + strip.background = element_rect(fill = "white", colour = "black", size = 1, inherit.blank = TRUE) # NB: size is 1 but clipped, it looks like the 0.5 of the axes ) } @@ -303,15 +304,13 @@ theme_void <- function(base_size = 11, base_family = "") { family = base_family, face = "plain", colour = "black", size = base_size, lineheight = 0.9, hjust = 0.5, vjust = 0.5, angle = 0, - margin = margin(), debug = FALSE + margin = margin(), debug = FALSE, inherit.blank = TRUE ), - axis.text.x = element_blank(), - axis.text.y = element_blank(), - axis.title.x = element_blank(), - axis.title.y = element_blank(), - legend.text = element_text(size = rel(0.8)), - legend.title = element_text(hjust = 0), - strip.text = element_text(size = rel(0.8)), + axis.text = element_blank(), + axis.title = element_blank(), + legend.text = element_text(size = rel(0.8), inherit.blank = TRUE), + legend.title = element_text(hjust = 0, inherit.blank = TRUE), + strip.text = element_text(size = rel(0.8), inherit.blank = TRUE), plot.margin = unit(c(0, 0, 0, 0), "lines"), complete = TRUE From aaa64e5c1c58b3f67bd0b68f8ea06de6c9505592 Mon Sep 17 00:00:00 2001 From: thomasp85 Date: Sat, 17 Sep 2016 10:18:15 +0200 Subject: [PATCH 4/9] News bullet --- NEWS.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/NEWS.md b/NEWS.md index 67556628b..7c568d323 100644 --- a/NEWS.md +++ b/NEWS.md @@ -17,6 +17,9 @@ I have also very slightly increased the inner margins of axis titles, and removed the outer margins. +* Theme element inheritance is now more easy to work with. Modification now + overrides default `element_blank` elements (#1555, #1557, #1565, #1567) + * Themes are more homogeneous visually, and match `theme_grey` better. (@jiho, #1679) From ace0dee375e2e4ea9a9b585d8c1dfd214f546042 Mon Sep 17 00:00:00 2001 From: thomasp85 Date: Sat, 17 Sep 2016 21:25:46 +0200 Subject: [PATCH 5/9] Better documentation --- R/theme-elements.r | 5 ++++- R/theme.r | 7 +++++-- man/element.Rd | 5 ++++- man/theme.Rd | 4 +++- 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/R/theme-elements.r b/R/theme-elements.r index a474be7aa..b4fcfbdeb 100644 --- a/R/theme-elements.r +++ b/R/theme-elements.r @@ -14,7 +14,10 @@ #' @param colour,color Line/border colour. Color is an alias for colour. #' @param size Line/border size in mm; text size in pts. #' @param inherit.blank Should this element inherit the existence of an -#' element_blank among its parents? +#' element_blank among its parents? If \code{TRUE} the existence of a blank +#' element among its parents will cause this element to be blank as well. If +#' \code{FALSE} any blank parent element will be ignored when calculating final +#' element state. #' @name element #' @return An S3 object of class \code{element}. #' @examples diff --git a/R/theme.r b/R/theme.r index 15aee36d7..1bdd8a93a 100644 --- a/R/theme.r +++ b/R/theme.r @@ -231,7 +231,9 @@ print.theme <- function(x, ...) utils::str(x) #' existing theme. #' @param complete set this to TRUE if this is a complete theme, such as #' the one returned \code{by theme_grey()}. Complete themes behave -#' differently when added to a ggplot object. +#' differently when added to a ggplot object. Also, when setting +#' \code{complete = TRUE} all elements will be set to inherit from blank +#' elements. #' @param validate TRUE to run validate_element, FALSE to bypass checks. #' #' @seealso \code{\link{+.gg}} @@ -636,7 +638,8 @@ combine_elements <- function(e1, e2) { if (is.null(e2) || inherits(e1, "element_blank")) return(e1) # If e1 is NULL inherit everything from e2 if (is.null(e1)) return(e2) - # If e1 is NULL, or if e2 is element_blank, inherit everything from e2 + # If e2 is element_blank, and e1 inherits blank inherit everything from e2, + # otherwise ignore e2 if (inherits(e2, "element_blank")) { if (e1$inherit.blank) return(e2) else return(e1) diff --git a/man/element.Rd b/man/element.Rd index f41409199..684b554f9 100644 --- a/man/element.Rd +++ b/man/element.Rd @@ -33,7 +33,10 @@ an even number (up to eight) of hexadecimal digits which give the lengths in consecutive positions in the string.} \item{inherit.blank}{Should this element inherit the existence of an -element_blank among its parents?} +element_blank among its parents? If \code{TRUE} the existence of a blank +element among its parents will cause this element to be blank as well. If +\code{FALSE} any blank parent element will be ignored when calculating final +element state.} \item{lineend}{Line end Line end style (round, butt, square)} diff --git a/man/theme.Rd b/man/theme.Rd index 7c119b71c..3ec723eb0 100644 --- a/man/theme.Rd +++ b/man/theme.Rd @@ -12,7 +12,9 @@ existing theme.} \item{complete}{set this to TRUE if this is a complete theme, such as the one returned \code{by theme_grey()}. Complete themes behave -differently when added to a ggplot object.} +differently when added to a ggplot object. Also, when setting +\code{complete = TRUE} all elements will be set to inherit from blank +elements.} \item{validate}{TRUE to run validate_element, FALSE to bypass checks.} } From 84fd9f5f40c696ce206c4da7422ce626522fe96e Mon Sep 17 00:00:00 2001 From: thomasp85 Date: Sat, 17 Sep 2016 21:26:15 +0200 Subject: [PATCH 6/9] Set inherit.blank = TRUE automatically when theme is complete --- R/theme-defaults.r | 113 ++++++++++++++++++++++++++--------------------------- R/theme.r | 9 +++++ 2 files changed, 64 insertions(+), 58 deletions(-) diff --git a/R/theme-defaults.r b/R/theme-defaults.r index cb175af5b..9a2e26505 100644 --- a/R/theme-defaults.r +++ b/R/theme-defaults.r @@ -79,33 +79,33 @@ theme_grey <- function(base_size = 11, base_family = "") { axis.line = element_blank(), axis.line.x = NULL, axis.line.y = NULL, - axis.text = element_text(size = rel(0.8), colour = "grey30", inherit.blank = TRUE), - axis.text.x = element_text(margin = margin(t = 0.8 * half_line / 2), vjust = 1, inherit.blank = TRUE), - axis.text.y = element_text(margin = margin(r = 0.8 * half_line / 2), hjust = 1, inherit.blank = TRUE), - axis.ticks = element_line(colour = "grey20", inherit.blank = TRUE), + axis.text = element_text(size = rel(0.8), colour = "grey30"), + axis.text.x = element_text(margin = margin(t = 0.8 * half_line / 2), vjust = 1), + axis.text.y = element_text(margin = margin(r = 0.8 * half_line / 2), hjust = 1), + axis.ticks = element_line(colour = "grey20"), axis.ticks.length = unit(half_line / 2, "pt"), axis.title.x = element_text( margin = margin(t = half_line), - vjust = 1, inherit.blank = TRUE + vjust = 1 ), axis.title.y = element_text( angle = 90, margin = margin(r = half_line), - vjust = 1, inherit.blank = TRUE + vjust = 1 ), - legend.background = element_rect(colour = NA, inherit.blank = TRUE), + legend.background = element_rect(colour = NA), legend.spacing = unit(0.4, "cm"), legend.spacing.x = NULL, legend.spacing.y = NULL, legend.margin = margin(0, 0, 0, 0, "cm"), - legend.key = element_rect(fill = "grey95", colour = "white", inherit.blank = TRUE), + legend.key = element_rect(fill = "grey95", colour = "white"), legend.key.size = unit(1.2, "lines"), legend.key.height = NULL, legend.key.width = NULL, - legend.text = element_text(size = rel(0.8), inherit.blank = TRUE), + legend.text = element_text(size = rel(0.8)), legend.text.align = NULL, - legend.title = element_text(hjust = 0, inherit.blank = TRUE), + legend.title = element_text(hjust = 0), legend.title.align = NULL, legend.position = "right", legend.direction = NULL, @@ -115,40 +115,37 @@ theme_grey <- function(base_size = 11, base_family = "") { legend.box.background = element_blank(), legend.box.spacing = unit(0.4, "cm"), - panel.background = element_rect(fill = "grey92", colour = NA, inherit.blank = TRUE), + panel.background = element_rect(fill = "grey92", colour = NA), panel.border = element_blank(), - panel.grid.major = element_line(colour = "white", inherit.blank = TRUE), - panel.grid.minor = element_line(colour = "white", size = 0.25, inherit.blank = TRUE), + panel.grid.major = element_line(colour = "white"), + panel.grid.minor = element_line(colour = "white", size = 0.25), panel.spacing = unit(half_line, "pt"), panel.spacing.x = NULL, panel.spacing.y = NULL, panel.ontop = FALSE, - strip.background = element_rect(fill = "grey85", colour = NA, inherit.blank = TRUE), - strip.text = element_text(colour = "grey10", size = rel(0.8), inherit.blank = TRUE), - strip.text.x = element_text(margin = margin(t = half_line, b = half_line), inherit.blank = TRUE), - strip.text.y = element_text(angle = -90, margin = margin(l = half_line, r = half_line), inherit.blank = TRUE), + strip.background = element_rect(fill = "grey85", colour = NA), + strip.text = element_text(colour = "grey10", size = rel(0.8)), + strip.text.x = element_text(margin = margin(t = half_line, b = half_line)), + strip.text.y = element_text(angle = -90, margin = margin(l = half_line, r = half_line)), strip.switch.pad.grid = unit(0.1, "cm"), strip.switch.pad.wrap = unit(0.1, "cm"), - plot.background = element_rect(colour = "white", inherit.blank = TRUE), + plot.background = element_rect(colour = "white"), plot.title = element_text( size = rel(1.2), hjust = 0, vjust = 1, - margin = margin(b = half_line * 1.2), - inherit.blank = TRUE + margin = margin(b = half_line * 1.2) ), plot.subtitle = element_text( size = rel(0.9), hjust = 0, vjust = 1, - margin = margin(b = half_line * 0.9), - inherit.blank = TRUE + margin = margin(b = half_line * 0.9) ), plot.caption = element_text( size = rel(0.9), hjust = 1, vjust = 1, - margin = margin(t = half_line * 0.9), - inherit.blank = TRUE + margin = margin(t = half_line * 0.9) ), plot.margin = margin(half_line, half_line, half_line, half_line), @@ -166,15 +163,15 @@ theme_bw <- function(base_size = 11, base_family = "") { theme_grey(base_size = base_size, base_family = base_family) %+replace% theme( # white background and dark border - panel.background = element_rect(fill = "white", colour = NA, inherit.blank = TRUE), - panel.border = element_rect(fill = NA, colour = "grey20", inherit.blank = TRUE), + panel.background = element_rect(fill = "white", colour = NA), + panel.border = element_rect(fill = NA, colour = "grey20"), # make gridlines dark, same contrast with white as in theme_grey - panel.grid.major = element_line(colour = "grey92", inherit.blank = TRUE), - panel.grid.minor = element_line(colour = "grey92", size = 0.25, inherit.blank = TRUE), + panel.grid.major = element_line(colour = "grey92"), + panel.grid.minor = element_line(colour = "grey92", size = 0.25), # contour strips to match panel contour - strip.background = element_rect(fill = "grey85", colour = "grey20", inherit.blank = TRUE), + strip.background = element_rect(fill = "grey85", colour = "grey20"), # match legend key to background - legend.key = element_rect(fill = "white", colour=NA, inherit.blank = TRUE) + legend.key = element_rect(fill = "white", colour=NA) ) } @@ -186,19 +183,19 @@ theme_linedraw <- function(base_size = 11, base_family = "") { theme_bw(base_size = base_size, base_family = base_family) %+replace% theme( # black text and ticks on the axes - axis.text = element_text(colour = "black", size = rel(0.8), inherit.blank = TRUE), - axis.ticks = element_line(colour = "black", size = 0.25, inherit.blank = TRUE), + axis.text = element_text(colour = "black", size = rel(0.8)), + axis.ticks = element_line(colour = "black", size = 0.25), # NB: match the *visual* thickness of axis ticks to the panel border # 0.5 clipped looks like 0.25 # pure black panel border and grid lines, but thinner - panel.border = element_rect(fill = NA, colour = "black", size = 0.5, inherit.blank = TRUE), - panel.grid.major = element_line(colour = "black", size = 0.05, inherit.blank = TRUE), - panel.grid.minor = element_line(colour = "black", size = 0.025, inherit.blank = TRUE), + panel.border = element_rect(fill = NA, colour = "black", size = 0.5), + panel.grid.major = element_line(colour = "black", size = 0.05), + panel.grid.minor = element_line(colour = "black", size = 0.025), # strips with black background and white text - strip.background = element_rect(fill = "black", inherit.blank = TRUE), - strip.text = element_text(colour = "white", size = rel(0.8), inherit.blank = TRUE) + strip.background = element_rect(fill = "black"), + strip.text = element_text(colour = "white", size = rel(0.8)) ) } @@ -209,22 +206,22 @@ theme_light <- function(base_size = 11, base_family = "") { theme_grey(base_size = base_size, base_family = base_family) %+replace% theme( # white panel with light grey border - panel.background = element_rect(fill = "white", colour = NA, inherit.blank = TRUE), - panel.border = element_rect(fill = NA, colour = "grey70", size = 0.5, inherit.blank = TRUE), + panel.background = element_rect(fill = "white", colour = NA), + panel.border = element_rect(fill = NA, colour = "grey70", size = 0.5), # light grey, thinner gridlines # => make them slightly darker to keep acceptable contrast - panel.grid.major = element_line(colour = "grey87", size = 0.25, inherit.blank = TRUE), - panel.grid.minor = element_line(colour = "grey87", size = 0.125, inherit.blank = TRUE), + panel.grid.major = element_line(colour = "grey87", size = 0.25), + panel.grid.minor = element_line(colour = "grey87", size = 0.125), # match axes ticks thickness to gridlines and colour to panel border - axis.ticks = element_line(colour = "grey70", size = 0.25, inherit.blank = TRUE), + axis.ticks = element_line(colour = "grey70", size = 0.25), # match legend key to panel.background - legend.key = element_rect(fill = "white", colour = NA, inherit.blank = TRUE), + legend.key = element_rect(fill = "white", colour = NA), # dark strips with light text (inverse contrast compared to theme_grey) - strip.background = element_rect(fill = "grey70", colour = NA, inherit.blank = TRUE), - strip.text = element_text(colour = "white", size = rel(0.8), inherit.blank = TRUE) + strip.background = element_rect(fill = "grey70", colour = NA), + strip.text = element_text(colour = "white", size = rel(0.8)) ) } @@ -236,21 +233,21 @@ theme_dark <- function(base_size = 11, base_family = "") { theme_grey(base_size = base_size, base_family = base_family) %+replace% theme( # dark panel - panel.background = element_rect(fill = "grey50", colour = NA, inherit.blank = TRUE), + panel.background = element_rect(fill = "grey50", colour = NA), # inverse grid lines contrast compared to theme_grey # make them thinner and try to keep the same visual contrast as in theme_light - panel.grid.major = element_line(colour = "grey42", size = 0.25, inherit.blank = TRUE), - panel.grid.minor = element_line(colour = "grey42", size = 0.125, inherit.blank = TRUE), + panel.grid.major = element_line(colour = "grey42", size = 0.25), + panel.grid.minor = element_line(colour = "grey42", size = 0.125), # match axes ticks thickness to gridlines - axis.ticks = element_line(colour = "grey20", size = 0.25, inherit.blank = TRUE), + axis.ticks = element_line(colour = "grey20", size = 0.25), # match legend key to panel.background - legend.key = element_rect(fill = "grey50", colour = NA, inherit.blank = TRUE), + legend.key = element_rect(fill = "grey50", colour = NA), # dark strips with light text (inverse contrast compared to theme_grey) - strip.background = element_rect(fill = "grey15", colour = NA, inherit.blank = TRUE), - strip.text = element_text(colour = "grey90", size = rel(0.8), inherit.blank = TRUE) + strip.background = element_rect(fill = "grey15", colour = NA), + strip.text = element_text(colour = "grey90", size = rel(0.8)) ) } @@ -281,13 +278,13 @@ theme_classic <- function(base_size = 11, base_family = ""){ panel.grid.minor = element_blank(), # show axes - axis.line = element_line(colour = "black", size = 0.5, inherit.blank = TRUE), + axis.line = element_line(colour = "black", size = 0.5), # match legend key to panel.background legend.key = element_blank(), # simple, black and white strips - strip.background = element_rect(fill = "white", colour = "black", size = 1, inherit.blank = TRUE) + strip.background = element_rect(fill = "white", colour = "black", size = 1) # NB: size is 1 but clipped, it looks like the 0.5 of the axes ) } @@ -304,13 +301,13 @@ theme_void <- function(base_size = 11, base_family = "") { family = base_family, face = "plain", colour = "black", size = base_size, lineheight = 0.9, hjust = 0.5, vjust = 0.5, angle = 0, - margin = margin(), debug = FALSE, inherit.blank = TRUE + margin = margin(), debug = FALSE ), axis.text = element_blank(), axis.title = element_blank(), - legend.text = element_text(size = rel(0.8), inherit.blank = TRUE), - legend.title = element_text(hjust = 0, inherit.blank = TRUE), - strip.text = element_text(size = rel(0.8), inherit.blank = TRUE), + legend.text = element_text(size = rel(0.8)), + legend.title = element_text(hjust = 0), + strip.text = element_text(size = rel(0.8)), plot.margin = unit(c(0, 0, 0, 0), "lines"), complete = TRUE diff --git a/R/theme.r b/R/theme.r index 1bdd8a93a..b7c12773c 100644 --- a/R/theme.r +++ b/R/theme.r @@ -417,6 +417,15 @@ theme <- function(..., complete = FALSE, validate = TRUE) { mapply(validate_element, elements, names(elements)) } + # If complete theme set all non-blank elements to inherit from blanks + if (complete) { + elements <- lapply(elements, function(el) { + if (inherits(el, "element") && !inherits(el, "element_blank")) { + el$inherit.blank <- TRUE + } + el + }) + } structure(elements, class = c("theme", "gg"), complete = complete, validate = validate) } From fdbe5d08cffad9eb80c6ad2435e6fd3f7acd6fa2 Mon Sep 17 00:00:00 2001 From: thomasp85 Date: Tue, 20 Sep 2016 15:47:49 +0200 Subject: [PATCH 7/9] Set all replacements to complete so inherit.blank is true --- R/theme-defaults.r | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/R/theme-defaults.r b/R/theme-defaults.r index 15fa88b02..215f276c5 100644 --- a/R/theme-defaults.r +++ b/R/theme-defaults.r @@ -185,7 +185,9 @@ theme_bw <- function(base_size = 11, base_family = "") { # contour strips to match panel contour strip.background = element_rect(fill = "grey85", colour = "grey20"), # match legend key to background - legend.key = element_rect(fill = "white", colour=NA) + legend.key = element_rect(fill = "white", colour=NA), + + complete = TRUE ) } @@ -209,7 +211,9 @@ theme_linedraw <- function(base_size = 11, base_family = "") { # strips with black background and white text strip.background = element_rect(fill = "black"), - strip.text = element_text(colour = "white", size = rel(0.8)) + strip.text = element_text(colour = "white", size = rel(0.8)), + + complete = TRUE ) } @@ -235,7 +239,9 @@ theme_light <- function(base_size = 11, base_family = "") { # dark strips with light text (inverse contrast compared to theme_grey) strip.background = element_rect(fill = "grey70", colour = NA), - strip.text = element_text(colour = "white", size = rel(0.8)) + strip.text = element_text(colour = "white", size = rel(0.8)), + + complete = TRUE ) } @@ -261,7 +267,9 @@ theme_dark <- function(base_size = 11, base_family = "") { # dark strips with light text (inverse contrast compared to theme_grey) strip.background = element_rect(fill = "grey15", colour = NA), - strip.text = element_text(colour = "grey90", size = rel(0.8)) + strip.text = element_text(colour = "grey90", size = rel(0.8)), + + complete = TRUE ) } @@ -277,7 +285,9 @@ theme_minimal <- function(base_size = 11, base_family = "") { panel.background = element_blank(), panel.border = element_blank(), strip.background = element_blank(), - plot.background = element_blank() + plot.background = element_blank(), + + complete = TRUE ) } @@ -298,8 +308,10 @@ theme_classic <- function(base_size = 11, base_family = ""){ legend.key = element_blank(), # simple, black and white strips - strip.background = element_rect(fill = "white", colour = "black", size = 1) + strip.background = element_rect(fill = "white", colour = "black", size = 1), # NB: size is 1 but clipped, it looks like the 0.5 of the axes + + complete = TRUE ) } From 30e5493984cf8648c917866cd3bd760ac473ce57 Mon Sep 17 00:00:00 2001 From: thomasp85 Date: Tue, 20 Sep 2016 15:48:03 +0200 Subject: [PATCH 8/9] Check value of inherit.blank --- tests/testthat/test-theme.r | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/testthat/test-theme.r b/tests/testthat/test-theme.r index 49238c998..0b029458d 100644 --- a/tests/testthat/test-theme.r +++ b/tests/testthat/test-theme.r @@ -51,6 +51,8 @@ test_that("Adding theme object to ggplot object with + operator", { expect_true(p$theme$text$colour == 'red') tt <- theme_grey()$text tt$colour <- 'red' + expect_true(tt$inherit.blank) + tt$inherit.blank <- FALSE expect_identical(p$theme$text, tt) }) From ea9b57ecfbdec8893ebe0e3b156aa339c17829d5 Mon Sep 17 00:00:00 2001 From: thomasp85 Date: Tue, 20 Sep 2016 17:10:17 +0200 Subject: [PATCH 9/9] Test all exported themes have inherit.blank = TRUE elements --- tests/testthat/test-theme.r | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/testthat/test-theme.r b/tests/testthat/test-theme.r index 0b029458d..75ad3fe1c 100644 --- a/tests/testthat/test-theme.r +++ b/tests/testthat/test-theme.r @@ -190,3 +190,23 @@ test_that("theme(validate=FALSE) means do not validate_element", { red.before <- p + red.text + theme(animint.width = 500, validate = FALSE) expect_equal(red.before$theme$animint.width, 500) }) + +test_that("All elements in complete themes have inherit.blank=TRUE", { + inherit_blanks <- function(theme) { + all(vapply(theme, function(el) { + if (inherits(el, "element") && !inherits(el, "element_blank")) { + el$inherit.blank + } else { + TRUE + } + }, logical(1))) + } + expect_true(inherit_blanks(theme_grey())) + expect_true(inherit_blanks(theme_bw())) + expect_true(inherit_blanks(theme_classic())) + expect_true(inherit_blanks(theme_dark())) + expect_true(inherit_blanks(theme_light())) + expect_true(inherit_blanks(theme_linedraw())) + expect_true(inherit_blanks(theme_minimal())) + expect_true(inherit_blanks(theme_void())) +})