Skip to content

Add inherit.blank argument to element constructors #1754

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Sep 21, 2016
3 changes: 3 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
129 changes: 64 additions & 65 deletions R/theme-defaults.r
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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),

Expand All @@ -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)
)
}

Expand All @@ -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)
)
}

Expand All @@ -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)
)

}
Expand All @@ -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)
)
}

Expand All @@ -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(),
Expand All @@ -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
)
}
Expand All @@ -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
Expand Down
15 changes: 9 additions & 6 deletions R/theme-elements.r
Original file line number Diff line number Diff line change
Expand Up @@ -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?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you expand on this a little bit? I assume if it's TRUE the "blank-ness" will be inherited, otherwise it will skip the parent and look at the grand parent?

#' @name element
#' @return An S3 object of class \code{element}.
#' @examples
Expand Down Expand Up @@ -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")
)
}
Expand All @@ -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")
)
}
Expand All @@ -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")
)
}
Expand Down
10 changes: 7 additions & 3 deletions R/theme.r
Original file line number Diff line number Diff line change
Expand Up @@ -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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment needs updating too, right?

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))
Expand Down
9 changes: 6 additions & 3 deletions man/element.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.