knitr::opts_chunk$set(echo = TRUE)
options(tidyverse.quiet = TRUE)



library(ggplot2)
p <- ggplot(mtcars, 
            aes(x = factor(cyl), 
                fill = factor(cyl))) +
  geom_bar() + 
  geom_point(stat = StatCount, size = 7) + 
  geom_tile(aes(y = -2, fill = NULL))

p +
  theme_void(ink = "plum", paper = "cornsilk", base_size = 18)

last_plot() + 
  theme(geom = element_geom(ink = "plum")) + 
  theme(plot.background = element_rect(fill = "whitesmoke", 
                                       linewidth = 0
                                       ))

library(ggplot2)
theme_void2 <- function (base_size = 11, base_family = "", header_family = NULL, 
    base_line_size = base_size/22, 
    # base_rect_size = base_size/22
    base_rect_size = 0, #<< 1. change the border size
    ink = "black", 
    paper = alpha("white", 0) #<< 2. change the paper color
    ) 
{
    half_line <- base_size/2
    t <- theme(line = element_blank(), 
               rect = element_blank(), 
               # rect = element_rect(fill = paper, colour = ink, #<< 3. change the rectangle setting
                                   # linewidth = base_rect_size, linetype = 1), 
        text = element_text(family = base_family, face = "plain", 
            colour = ink, size = base_size, lineheight = 0.9, 
            hjust = 0.5, vjust = 0.5, angle = 0, margin = margin(), 
            debug = FALSE), title = element_text(family = header_family), 
        spacing = unit(half_line, "pt"), margins = margin(half_line, 
            half_line, half_line, half_line), axis.text = element_blank(), 
        axis.title = element_blank(), axis.ticks.length = rel(0), 
        axis.ticks.length.x = NULL, axis.ticks.length.x.top = NULL, 
        axis.ticks.length.x.bottom = NULL, axis.ticks.length.y = NULL, 
        axis.ticks.length.y.left = NULL, axis.ticks.length.y.right = NULL, 
        axis.minor.ticks.length = NULL, legend.box = NULL, 
        legend.key.size = unit(1.2, "lines"), legend.position = "right", 
        legend.text = element_text(size = rel(0.8)), 
        legend.title = element_text(hjust = 0), legend.key.spacing = rel(1), 
        legend.margin = rel(0), legend.box.margin = rel(0), legend.box.spacing = unit(0.2, 
            "cm"), legend.ticks.length = rel(0.2), strip.clip = "on", 
        strip.text = element_text(size = rel(0.8)), strip.switch.pad.grid = rel(0.5), 
        strip.switch.pad.wrap = rel(0.5), panel.ontop = FALSE, 
        panel.spacing = NULL, 
        
        plot.margin = rel(0), plot.title = element_text(size = rel(1.2), 
            hjust = 0, vjust = 1, margin = margin(t = half_line)), 
        plot.title.position = "panel", plot.subtitle = element_text(hjust = 0, 
            vjust = 1, margin = margin(t = half_line)), plot.caption = element_text(size = rel(0.8), 
            hjust = 1, vjust = 1, margin = margin(t = half_line)), 
        plot.caption.position = "panel", plot.tag = element_text(size = rel(1.2), 
            hjust = 0.5, vjust = 0.5), plot.tag.position = "topleft", 
        # try to make plot.background more flexible
        plot.background = element_rect(fill = paper),  #<< 4. add the plot background
            # try to make geom responsive
        geom = element_geom(ink = ink, paper = paper, accent = "#3366FF", linewidth = base_line_size, 
            borderwidth = base_line_size, linetype = 1L, bordertype = 1L, 
            family = base_family, fontsize = base_size, pointsize = (base_size/11) * 
                1.5, pointshape = 19), 
        complete = TRUE)
    ggplot2:::ggplot_global$theme_all_null %+replace% t
}


ggplot(mtcars, 
            aes(x = factor(cyl), 
                fill = factor(cyl))) +
  geom_bar() + 
  geom_point(stat = StatCount, size = 7) + 
  geom_tile(aes(y = -2, fill = NULL))

last_plot() + 
  theme_void()

last_plot() + 
  theme_void2()

last_plot() + 
  theme_void(ink = "plum", paper = "cornsilk")

last_plot() + 
  theme_void2(ink = "plum", paper = "cornsilk")

last_plot() + 
  ggraph::theme_graph(background = "cornsilk") + 
  theme(geom = element_geom(ink = "plum"))

theme_grey = function (base_size = 11, base_family = "", header_family = NULL, 
    base_line_size = base_size/22, base_rect_size = base_size/22, 
    ink = "black", paper = "white") 
{
    half_line <- base_size/2
    t <- theme(
      line = element_line(colour = ink, linewidth = base_line_size, 
        linetype = 1, lineend = "butt"), 
        rect = element_rect(fill = paper, colour = ink, linewidth = base_rect_size, linetype = 1), ## update
        text = element_text(family = base_family, face = "plain", 
            colour = ink, size = base_size, lineheight = 0.9, 
            hjust = 0.5, vjust = 0.5, angle = 0, margin = margin(), 
            debug = FALSE), title = element_text(family = header_family), 
        spacing = unit(half_line, "pt"), 
      margins = margin(half_line, 
            half_line, half_line, half_line), 
      geom = element_geom(ink = ink, paper = paper, accent = "#3366FF", linewidth = base_line_size, 
            borderwidth = base_line_size, linetype = 1L, bordertype = 1L, 
            family = base_family, fontsize = base_size, pointsize = (base_size/11) * 
                1.5, pointshape = 19), 
      axis.line = element_blank(), 
        axis.line.x = NULL, axis.line.y = NULL, axis.text = element_text(size = rel(0.8), 
            colour = col_mix(ink, paper, 0.305)), axis.text.x = element_text(margin = margin(t = 0.8 * 
            half_line/2), vjust = 1), axis.text.x.top = element_text(margin = margin(b = 0.8 * 
            half_line/2), vjust = 0), axis.text.y = element_text(margin = margin(r = 0.8 * 
            half_line/2), hjust = 1), axis.text.y.right = element_text(margin = margin(l = 0.8 * 
            half_line/2), hjust = 0), axis.text.r = element_text(margin = margin(l = 0.8 * 
            half_line/2, r = 0.8 * half_line/2), hjust = 0.5), 
        axis.ticks = element_line(colour = col_mix(ink, paper, 
            0.2)), axis.ticks.length = rel(0.5), axis.ticks.length.x = NULL, 
        axis.ticks.length.x.top = NULL, axis.ticks.length.x.bottom = NULL, 
        axis.ticks.length.y = NULL, axis.ticks.length.y.left = NULL, 
        axis.ticks.length.y.right = NULL, axis.minor.ticks.length = rel(0.75), 
        axis.title.x = element_text(margin = margin(t = half_line/2), 
            vjust = 1), axis.title.x.top = element_text(margin = margin(b = half_line/2), 
            vjust = 0), axis.title.y = element_text(angle = 90, 
            margin = margin(r = half_line/2), vjust = 1), axis.title.y.right = element_text(angle = -90, 
            margin = margin(l = half_line/2), vjust = 1), legend.background = element_rect(colour = NA), 
        legend.spacing = rel(2), legend.spacing.x = NULL, legend.spacing.y = NULL, 
        legend.margin = NULL, legend.key = NULL, legend.key.size = unit(1.2, 
            "lines"), legend.key.height = NULL, legend.key.width = NULL, 
        legend.key.spacing = NULL, legend.text = element_text(size = rel(0.8)), 
        legend.title = element_text(hjust = 0), legend.ticks.length = rel(0.2), 
        legend.position = "right", legend.direction = NULL, legend.justification = "center", 
        legend.box = NULL, legend.box.margin = rel(0), legend.box.background = element_blank(), 
        legend.box.spacing = rel(2), panel.background = element_rect(fill = col_mix(ink, 
            paper, 0.925), colour = NA), panel.border = element_blank(), 
        panel.grid = element_line(colour = paper), panel.grid.minor = element_line(linewidth = rel(0.5)), 
        panel.spacing = NULL, panel.spacing.x = NULL, panel.spacing.y = NULL, 
        panel.ontop = FALSE, strip.background = element_rect(fill = col_mix(ink, 
            paper, 0.854), colour = NA), strip.clip = "on", strip.text = element_text(colour = col_mix(ink, 
            paper, 0.105), size = rel(0.8), margin = margin(0.8 * 
            half_line, 0.8 * half_line, 0.8 * half_line, 0.8 * 
            half_line)), strip.text.x = NULL, strip.text.y = element_text(angle = -90), 
        strip.text.y.left = element_text(angle = 90), strip.placement = "inside", 
        strip.placement.x = NULL, strip.placement.y = NULL, strip.switch.pad.grid = unit(half_line/2, 
            "pt"), strip.switch.pad.wrap = unit(half_line/2, 
            "pt"), plot.background = element_rect(colour = paper), 
        plot.title = element_text(size = rel(1.2), hjust = 0, 
            vjust = 1, margin = margin(b = half_line)), plot.title.position = "panel", 
        plot.subtitle = element_text(hjust = 0, vjust = 1, margin = margin(b = half_line)), 
        plot.caption = element_text(size = rel(0.8), hjust = 1, 
            vjust = 1, margin = margin(t = half_line)), plot.caption.position = "panel", 
        plot.tag = element_text(size = rel(1.2), hjust = 0.5, 
            vjust = 0.5), plot.tag.position = "topleft", plot.margin = NULL, 
        complete = TRUE)
    ggplot_global$theme_all_null %+replace% t
}

Intro Thoughts

Status Quo

library(tidyverse)

Experiment

ggraph::theme_graph()
## List of 139
##  $ line                            :List of 7
##   ..$ colour       : chr "black"
##   ..$ linewidth    : num 0.5
##   ..$ linetype     : num 1
##   ..$ lineend      : chr "butt"
##   ..$ arrow        : logi FALSE
##   ..$ arrow.fill   : chr "black"
##   ..$ inherit.blank: logi TRUE
##   ..- attr(*, "class")= chr [1:2] "element_line" "element"
##  $ rect                            :List of 5
##   ..$ fill         : chr "white"
##   ..$ colour       : chr "black"
##   ..$ linewidth    : num 0.5
##   ..$ linetype     : num 1
##   ..$ inherit.blank: logi TRUE
##   ..- attr(*, "class")= chr [1:2] "element_rect" "element"
##  $ text                            :List of 11
##   ..$ family       : chr "Arial Narrow"
##   ..$ face         : chr "plain"
##   ..$ colour       : chr "black"
##   ..$ size         : num 11
##   ..$ hjust        : num 0.5
##   ..$ vjust        : num 0.5
##   ..$ angle        : num 0
##   ..$ lineheight   : num 0.9
##   ..$ margin       : 'margin' num [1:4] 0points 0points 0points 0points
##   .. ..- attr(*, "unit")= int 8
##   ..$ debug        : logi FALSE
##   ..$ inherit.blank: logi FALSE
##   ..- attr(*, "class")= chr [1:2] "element_text" "element"
##  $ title                           :List of 11
##   ..$ family       : NULL
##   ..$ face         : NULL
##   ..$ colour       : NULL
##   ..$ size         : NULL
##   ..$ hjust        : NULL
##   ..$ vjust        : NULL
##   ..$ angle        : NULL
##   ..$ lineheight   : NULL
##   ..$ margin       : NULL
##   ..$ debug        : NULL
##   ..$ inherit.blank: logi TRUE
##   ..- attr(*, "class")= chr [1:2] "element_text" "element"
##  $ geom                            :List of 12
##   ..$ ink          : chr "black"
##   ..$ paper        : chr "white"
##   ..$ accent       : chr "#3366FF"
##   ..$ linewidth    : num 0.5
##   ..$ borderwidth  : num 0.5
##   ..$ linetype     : int 1
##   ..$ bordertype   : int 1
##   ..$ family       : chr "Arial Narrow"
##   ..$ fontsize     : num 3.87
##   ..$ pointsize    : num 1.5
##   ..$ pointshape   : num 19
##   ..$ inherit.blank: logi TRUE
##   ..- attr(*, "class")= chr [1:2] "element_geom" "element"
##  $ spacing                         : 'simpleUnit' num 5.5points
##   ..- attr(*, "unit")= int 8
##  $ margins                         : 'margin' num [1:4] 5.5points 5.5points 5.5points 5.5points
##   ..- attr(*, "unit")= int 8
##  $ aspect.ratio                    : NULL
##  $ axis.title                      : list()
##   ..- attr(*, "class")= chr [1:2] "element_blank" "element"
##  $ axis.title.x                    :List of 11
##   ..$ family       : NULL
##   ..$ face         : NULL
##   ..$ colour       : NULL
##   ..$ size         : NULL
##   ..$ hjust        : NULL
##   ..$ vjust        : num 1
##   ..$ angle        : NULL
##   ..$ lineheight   : NULL
##   ..$ margin       : 'margin' num [1:4] 2.75points 0points 0points 0points
##   .. ..- attr(*, "unit")= int 8
##   ..$ debug        : NULL
##   ..$ inherit.blank: logi TRUE
##   ..- attr(*, "class")= chr [1:2] "element_text" "element"
##  $ axis.title.x.top                :List of 11
##   ..$ family       : NULL
##   ..$ face         : NULL
##   ..$ colour       : NULL
##   ..$ size         : NULL
##   ..$ hjust        : NULL
##   ..$ vjust        : num 0
##   ..$ angle        : NULL
##   ..$ lineheight   : NULL
##   ..$ margin       : 'margin' num [1:4] 0points 0points 2.75points 0points
##   .. ..- attr(*, "unit")= int 8
##   ..$ debug        : NULL
##   ..$ inherit.blank: logi TRUE
##   ..- attr(*, "class")= chr [1:2] "element_text" "element"
##  $ axis.title.x.bottom             : NULL
##  $ axis.title.y                    :List of 11
##   ..$ family       : NULL
##   ..$ face         : NULL
##   ..$ colour       : NULL
##   ..$ size         : NULL
##   ..$ hjust        : NULL
##   ..$ vjust        : num 1
##   ..$ angle        : num 90
##   ..$ lineheight   : NULL
##   ..$ margin       : 'margin' num [1:4] 0points 2.75points 0points 0points
##   .. ..- attr(*, "unit")= int 8
##   ..$ debug        : NULL
##   ..$ inherit.blank: logi TRUE
##   ..- attr(*, "class")= chr [1:2] "element_text" "element"
##  $ axis.title.y.left               : NULL
##  $ axis.title.y.right              :List of 11
##   ..$ family       : NULL
##   ..$ face         : NULL
##   ..$ colour       : NULL
##   ..$ size         : NULL
##   ..$ hjust        : NULL
##   ..$ vjust        : num 1
##   ..$ angle        : num -90
##   ..$ lineheight   : NULL
##   ..$ margin       : 'margin' num [1:4] 0points 0points 0points 2.75points
##   .. ..- attr(*, "unit")= int 8
##   ..$ debug        : NULL
##   ..$ inherit.blank: logi TRUE
##   ..- attr(*, "class")= chr [1:2] "element_text" "element"
##  $ axis.text                       : list()
##   ..- attr(*, "class")= chr [1:2] "element_blank" "element"
##  $ axis.text.x                     :List of 11
##   ..$ family       : NULL
##   ..$ face         : NULL
##   ..$ colour       : NULL
##   ..$ size         : NULL
##   ..$ hjust        : NULL
##   ..$ vjust        : num 1
##   ..$ angle        : NULL
##   ..$ lineheight   : NULL
##   ..$ margin       : 'margin' num [1:4] 2.2points 0points 0points 0points
##   .. ..- attr(*, "unit")= int 8
##   ..$ debug        : NULL
##   ..$ inherit.blank: logi TRUE
##   ..- attr(*, "class")= chr [1:2] "element_text" "element"
##  $ axis.text.x.top                 :List of 11
##   ..$ family       : NULL
##   ..$ face         : NULL
##   ..$ colour       : NULL
##   ..$ size         : NULL
##   ..$ hjust        : NULL
##   ..$ vjust        : num 0
##   ..$ angle        : NULL
##   ..$ lineheight   : NULL
##   ..$ margin       : 'margin' num [1:4] 0points 0points 2.2points 0points
##   .. ..- attr(*, "unit")= int 8
##   ..$ debug        : NULL
##   ..$ inherit.blank: logi TRUE
##   ..- attr(*, "class")= chr [1:2] "element_text" "element"
##  $ axis.text.x.bottom              : NULL
##  $ axis.text.y                     :List of 11
##   ..$ family       : NULL
##   ..$ face         : NULL
##   ..$ colour       : NULL
##   ..$ size         : NULL
##   ..$ hjust        : num 1
##   ..$ vjust        : NULL
##   ..$ angle        : NULL
##   ..$ lineheight   : NULL
##   ..$ margin       : 'margin' num [1:4] 0points 2.2points 0points 0points
##   .. ..- attr(*, "unit")= int 8
##   ..$ debug        : NULL
##   ..$ inherit.blank: logi TRUE
##   ..- attr(*, "class")= chr [1:2] "element_text" "element"
##  $ axis.text.y.left                : NULL
##  $ axis.text.y.right               :List of 11
##   ..$ family       : NULL
##   ..$ face         : NULL
##   ..$ colour       : NULL
##   ..$ size         : NULL
##   ..$ hjust        : num 0
##   ..$ vjust        : NULL
##   ..$ angle        : NULL
##   ..$ lineheight   : NULL
##   ..$ margin       : 'margin' num [1:4] 0points 0points 0points 2.2points
##   .. ..- attr(*, "unit")= int 8
##   ..$ debug        : NULL
##   ..$ inherit.blank: logi TRUE
##   ..- attr(*, "class")= chr [1:2] "element_text" "element"
##  $ axis.text.theta                 : NULL
##  $ axis.text.r                     :List of 11
##   ..$ family       : NULL
##   ..$ face         : NULL
##   ..$ colour       : NULL
##   ..$ size         : NULL
##   ..$ hjust        : num 0.5
##   ..$ vjust        : NULL
##   ..$ angle        : NULL
##   ..$ lineheight   : NULL
##   ..$ margin       : 'margin' num [1:4] 0points 2.2points 0points 2.2points
##   .. ..- attr(*, "unit")= int 8
##   ..$ debug        : NULL
##   ..$ inherit.blank: logi TRUE
##   ..- attr(*, "class")= chr [1:2] "element_text" "element"
##  $ axis.ticks                      : list()
##   ..- attr(*, "class")= chr [1:2] "element_blank" "element"
##  $ axis.ticks.x                    : NULL
##  $ axis.ticks.x.top                : NULL
##  $ axis.ticks.x.bottom             : NULL
##  $ axis.ticks.y                    : NULL
##  $ axis.ticks.y.left               : NULL
##  $ axis.ticks.y.right              : NULL
##  $ axis.ticks.theta                : NULL
##  $ axis.ticks.r                    : NULL
##  $ axis.minor.ticks.x.top          : NULL
##  $ axis.minor.ticks.x.bottom       : NULL
##  $ axis.minor.ticks.y.left         : NULL
##  $ axis.minor.ticks.y.right        : NULL
##  $ axis.minor.ticks.theta          : NULL
##  $ axis.minor.ticks.r              : NULL
##  $ axis.ticks.length               : 'rel' num 0.5
##  $ axis.ticks.length.x             : NULL
##  $ axis.ticks.length.x.top         : NULL
##  $ axis.ticks.length.x.bottom      : NULL
##  $ axis.ticks.length.y             : NULL
##  $ axis.ticks.length.y.left        : NULL
##  $ axis.ticks.length.y.right       : NULL
##  $ axis.ticks.length.theta         : NULL
##  $ axis.ticks.length.r             : NULL
##  $ axis.minor.ticks.length         : 'rel' num 0.75
##  $ axis.minor.ticks.length.x       : NULL
##  $ axis.minor.ticks.length.x.top   : NULL
##  $ axis.minor.ticks.length.x.bottom: NULL
##  $ axis.minor.ticks.length.y       : NULL
##  $ axis.minor.ticks.length.y.left  : NULL
##  $ axis.minor.ticks.length.y.right : NULL
##  $ axis.minor.ticks.length.theta   : NULL
##  $ axis.minor.ticks.length.r       : NULL
##  $ axis.line                       : list()
##   ..- attr(*, "class")= chr [1:2] "element_blank" "element"
##  $ axis.line.x                     : NULL
##  $ axis.line.x.top                 : NULL
##  $ axis.line.x.bottom              : NULL
##  $ axis.line.y                     : NULL
##  $ axis.line.y.left                : NULL
##  $ axis.line.y.right               : NULL
##  $ axis.line.theta                 : NULL
##  $ axis.line.r                     : NULL
##  $ legend.background               : list()
##   ..- attr(*, "class")= chr [1:2] "element_blank" "element"
##  $ legend.margin                   : NULL
##  $ legend.spacing                  : 'rel' num 2
##  $ legend.spacing.x                : NULL
##  $ legend.spacing.y                : NULL
##  $ legend.key                      : list()
##   ..- attr(*, "class")= chr [1:2] "element_blank" "element"
##  $ legend.key.size                 : 'simpleUnit' num 1.2lines
##   ..- attr(*, "unit")= int 3
##  $ legend.key.height               : NULL
##  $ legend.key.width                : NULL
##  $ legend.key.spacing              : NULL
##  $ legend.key.spacing.x            : NULL
##  $ legend.key.spacing.y            : NULL
##  $ legend.frame                    : NULL
##  $ legend.ticks                    : NULL
##  $ legend.ticks.length             : 'rel' num 0.2
##  $ legend.axis.line                : NULL
##  $ legend.text                     :List of 11
##   ..$ family       : NULL
##   ..$ face         : NULL
##   ..$ colour       : NULL
##   ..$ size         : 'rel' num 0.8
##   ..$ hjust        : NULL
##   ..$ vjust        : NULL
##   ..$ angle        : NULL
##   ..$ lineheight   : NULL
##   ..$ margin       : NULL
##   ..$ debug        : NULL
##   ..$ inherit.blank: logi TRUE
##   ..- attr(*, "class")= chr [1:2] "element_text" "element"
##  $ legend.text.position            : NULL
##  $ legend.title                    :List of 11
##   ..$ family       : NULL
##   ..$ face         : NULL
##   ..$ colour       : NULL
##   ..$ size         : NULL
##   ..$ hjust        : num 0
##   ..$ vjust        : NULL
##   ..$ angle        : NULL
##   ..$ lineheight   : NULL
##   ..$ margin       : NULL
##   ..$ debug        : NULL
##   ..$ inherit.blank: logi TRUE
##   ..- attr(*, "class")= chr [1:2] "element_text" "element"
##  $ legend.title.position           : NULL
##  $ legend.position                 : chr "right"
##  $ legend.position.inside          : NULL
##  $ legend.direction                : NULL
##  $ legend.byrow                    : NULL
##  $ legend.justification            : chr "center"
##  $ legend.justification.top        : NULL
##  $ legend.justification.bottom     : NULL
##  $ legend.justification.left       : NULL
##  $ legend.justification.right      : NULL
##  $ legend.justification.inside     : NULL
##  $ legend.location                 : NULL
##  $ legend.box                      : NULL
##  $ legend.box.just                 : NULL
##   [list output truncated]
##  - attr(*, "class")= chr [1:2] "theme" "gg"
##  - attr(*, "complete")= logi TRUE
##  - attr(*, "validate")= logi TRUE

Closing remarks, Other Relevant Work, Caveats