Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ export(palette_okabeito)
export(palette_pizza)
export(palette_see)
export(palette_social)
export(palette_tol_discrete)
export(pizza_colors)
export(plots)
export(scale_color_bluebrown)
Expand Down Expand Up @@ -138,6 +139,7 @@ export(scale_color_see_d)
export(scale_color_social)
export(scale_color_social_c)
export(scale_color_social_d)
export(scale_color_tol_discrete)
export(scale_colour_bluebrown)
export(scale_colour_bluebrown_c)
export(scale_colour_bluebrown_d)
Expand All @@ -164,6 +166,7 @@ export(scale_colour_see_d)
export(scale_colour_social)
export(scale_colour_social_c)
export(scale_colour_social_d)
export(scale_colour_tol_discrete)
export(scale_fill_bluebrown)
export(scale_fill_bluebrown_c)
export(scale_fill_bluebrown_d)
Expand All @@ -190,6 +193,7 @@ export(scale_fill_see_d)
export(scale_fill_social)
export(scale_fill_social_c)
export(scale_fill_social_d)
export(scale_fill_tol_discrete)
export(see_colors)
export(social_colors)
export(theme_abyss)
Expand All @@ -199,4 +203,5 @@ export(theme_lucid)
export(theme_modern)
export(theme_radar)
export(theme_radar_dark)
export(tol_colors)
import(ggplot2)
5 changes: 3 additions & 2 deletions R/scale_color_flat.R
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ scale_fill_flat_d <- function(
)
}


#' @rdname scale_color_flat
#' @export
scale_fill_flat_c <- function(
Expand Down Expand Up @@ -271,10 +272,10 @@ flat_palettes <- list(
#' which are the two scale useful for discrete or gradient color scales,
#' respectively.
#' @param reverse Boolean indicating whether the palette should be reversed.
#' @param ... Additional arguments to pass to [`colorRampPalette()`][colorRampPalette].
#' @param ... Additional arguments to pass to [`grDevices::colorRampPalette()`].
#'
#' @details This function is usually not called directly, but from within
#' [`scale_color_flat()`][scale_color_flat].
#' [`scale_color_flat()`].
#'
#' @export
palette_flat <- function(palette = "contrast", reverse = FALSE, ...) {
Expand Down
2 changes: 1 addition & 1 deletion R/scale_color_metro.R
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ metro_palettes <- list(
"red"
),
contrast = metro_colors("blue", "green", "amber", "purple", "red"),
light = material_colors(
light = metro_colors(
"light blue",
"red",
"yellow",
Expand Down
22 changes: 12 additions & 10 deletions R/scale_color_okabeito.R
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@
#' the original yellow color suggested by Okabe and Ito (`"#F0E442"`), use
#' palettes `"full_original"` or `"black_first_original"`.
#'
#' The Okabe-Ito palette is only available as a discrete palette. For
#' color-accessible continuous variables, consider [the viridis
#' palettes][ggplot2::scale_colour_viridis_d()].
#' The Okabe-Ito palette is only available as a discrete palette.
#' For color-accessible continuous variables, consider
#' [Paul Tol's palettes][scale_color_tol_discrete()] or
#' [the viridis palettes][ggplot2::scale_colour_viridis_d()].
#'
#' @inheritParams palette_okabeito
#' @inheritParams scale_color_flat
Expand Down Expand Up @@ -120,6 +121,7 @@ scale_fill_oi <- scale_fill_okabeito
# Palette --------------------------------------------------------------------

# The palette from: https://jfly.uni-koeln.de/color/#pallet
# or grDevices::palette.colors()
okabeito_colors_list <- c(
orange = "#E69F00",
`light blue` = "#56B4E9",
Expand Down Expand Up @@ -147,11 +149,11 @@ okabeito_colors_list <- c(
#' @inheritParams flat_colors
#' @param original_names Logical. Should the colors be named using the original
#' names used by Okabe and Ito (2008), such as "vermillion" (`TRUE`), or
#' simplified names, such as "red" (`FALSE`, default)?
#' Only used if no colors are specified (to see all available colors).
#' @param black_first Logical. Should black be first (`TRUE`) or last (`FALSE`, default)
#' in the color palette? Only used if no colors are specified (to see all
#' available colors).
#' simplified names, such as "red" (`FALSE`, default)? Only used if no colors
#' are specified (to see all available colors).
#' @param black_first Logical. Should black be first (`TRUE`) or last (`FALSE`,
#' default) in the color palette? Only used if no colors are specified (to see
#' all available colors).
#' @param amber If amber color should replace yellow in the palette.
#'
#' @return A character vector with color-codes.
Expand Down Expand Up @@ -226,7 +228,7 @@ okabeito_palettes <- list(

#' Okabe-Ito color palette
#'
#' The palette based proposed by Okabe and Ito (2008).
#' The palette based on Okabe and Ito (2008).
#'
#' @inheritParams palette_flat
#' @param order A vector of numbers from 1 to 9 indicating the order of colors to use
Expand All @@ -238,7 +240,7 @@ okabeito_palettes <- list(
#' https://jfly.uni-koeln.de/color/#pallet (Original work published 2002)
#'
#' @details This function is usually not called directly, but from within
#' [`scale_color_material()`][scale_color_material].
#' [`scale_color_okabeito()`][scale_color_okabeito].
#'
#' @export
palette_okabeito <- function(
Expand Down
2 changes: 1 addition & 1 deletion R/scale_color_pizza.R
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ pizza_palettes <- list(
#' @param palette Pizza type. Can be `"margherita"` (default), `"margherita crust"`,
#' `"diavola"` or `"diavola crust"`.
#' @param reverse Boolean indicating whether the palette should be reversed.
#' @param ... Additional arguments to pass to [`colorRampPalette()`][colorRampPalette].
#' @param ... Additional arguments to pass to [`grDevices::colorRampPalette()`].
#'
#' @details This function is usually not called directly, but from within
#' [`scale_color_pizza()`][scale_color_pizza].
Expand Down
241 changes: 241 additions & 0 deletions R/scale_color_tol.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
#' Paul Tol discrete/qualitative color palettes
#'
#' Tol (2021) presents a series of palettes built with mathematical principles
#' that are appropriate for diverse types of data. The colors in these schemes
#' are:
#' - Visually distinct for all people, including viewers with color vision
#' deficiencies
#' - Distinct from black and white
#' - Distinct on screen and paper,
#' - Cohesive; that is, they match well together
#'
#' Tol provides palettes appropriate to the 3 main types of data:
#' 1. Qualitative data – nominal or categorical data, where magnitude
#' differences are not relevant.
#' 2. Diverging data – data ordered between two extremes where the midpoint is
#' important.
#' 3. Sequential data – data ordered from low to high.
#'
#' This function provides the qualitative palettes, as well as discrete rainbow
#' sequential palettes. Available palettes for each type of data are:
#' - Qualitative: `bright`, `high-contrast`, `vibrant`, `muted`,
#' `medium-contrast`, `pale`, `dark`, `light`, `ground_cover`
#' - Diverging: `sunset`, `nightfall`, `BuRd`, `PRGn`
#' - Sequential: `YlOrBr`, `iridescent`, `rainbow_discrete`, `rainbow_smooth`
#'
#' <!-- For rainbow_discrete, pick the optimal set based on the number of colors,
#' For rainbow_smooth, include a range argument with examples to start/end at off-white vs. purple, red vs brown
#' -->
#'
#' <!-- put a table with recommended uses here -->
#'
#' ## Colors for missing or invalid data
#'
#' A useful feature of Tol's diverging and sequential palettes is that he
#' provides a recommended color to use for data that fall outside the data range
#' represented by the color scale (e.g., for invalid or missing data). These
#' colors are chosen to be highly distinct from the main color palette.
#'
#' @inheritParams palette_tol_discrete
#' @inheritParams scale_color_flat
#'
#' @references
#' Tol, P. (2021). Colour schemes (SRON/EPS Technical Note No. 09-002; Version 3.2).
#' SRON. https://personal.sron.nl/~pault/data/colourschemes.pdf (Original work published 2009)
#'
#' @examples
#' library(ggplot2)
#' library(see)
#'
#' ggplot(iris, aes(x = Species, y = Sepal.Length, fill = Species)) +
#' geom_boxplot() +
#' theme_modern() +
#' scale_fill_okabeito()
#'
#' ggplot(iris, aes(x = Species, y = Sepal.Length, fill = Species)) +
#' geom_violin() +
#' theme_modern() +
#' scale_fill_oi(palette = "black_first")
#'
#' # for the original brighter yellow color suggested by Okabe and Ito
#' ggplot(iris, aes(x = Species, y = Sepal.Length, fill = Species)) +
#' geom_violin() +
#' theme_modern() +
#' scale_fill_oi(palette = "full")
#'
#' ggplot(iris, aes(x = Species, y = Sepal.Length, fill = Species)) +
#' geom_violin() +
#' theme_modern() +
#' scale_fill_oi(order = c(1, 5, 6, 2, 4, 3, 7))
#' @export
scale_color_tol_discrete <- function(palette = "bright", reverse = FALSE, order = NULL, aesthetics = "color", ...) {
discrete_scale(
aesthetics = aesthetics,
palette = palette_tol_discrete(palette = palette, reverse = reverse, order = order),
...
)
}

# Fill --------------------------------------------------------------------

#' @rdname scale_color_tol_discrete
#' @export
scale_fill_tol_discrete <- function(palette = "bright", reverse = FALSE, order = NULL, aesthetics = "fill", ...) {
discrete_scale(
aesthetics = aesthetics,
palette = palette_tol_discrete(palette = palette, reverse = reverse, order = order),
...
)
}

# Aliases -----------------------------------------------------------------

#' @rdname scale_color_tol_discrete
#' @export
scale_colour_tol_discrete <- scale_color_tol_discrete


# Palette --------------------------------------------------------------------

tol_colors_discrete_list <- list(
bright = c(blue = "#4477AA", red = "#EE6677", green = "#228833", yellow = "#CCBB44", cyan = "#66CCEE", purple = "#AA3377", grey = "#BBBBBB"),
`high-contrast` = c(blue = "#004488", yellow = "#DDAA33", red = "#BB5566", black = "#000000", white = "#FFFFFF"),
vibrant = c(orange = "#EE7733", blue = "#0077BB", cyan = "#33BBEE", magenta = "#EE3377", red = "#CC3311", teal = "#009988", grey = "#BBBBBB"),
muted = c(rose = "#CC6677", indigo = "#332288", sand = "#DDCC77", green = "#117733", cyan = "#88CCEE", wine = "#882255", teal = "#44AA99", olive = "#999933", purple = "#AA4499", grey = "#DDDDDD"),
`medium-contrast` = c("light blue" = "#6699CC", "dark blue" = "#004488", "light yellow" = "#EECC66", "dark red" = "#994455", "dark yellow" = "#997700", "light red" = "#EE99AA", black = "#000000", white = "#FFFFFF"),
pale = c(blue = "#BBCCEE", cyan = "#CCEEFF", green = "#CCDDAA", yellow = "#EEEEBB", red = "#FFCCCC", grey = "#DDDDDD"),
dark = c(blue = "#222255", cyan = "#225555", green = "#225522", yellow = "#666633", red = "#663333", grey = "#555555"),
light = c(blue = "#77AADD", orange = "#EE8866", yellow = "#EEDD88", pink = "#FFAABB", cyan = "#99DDFF", mint = "#44BB99", pear = "#BBCC33", olive = "#AAAA00", grey = "#DDDDDD"),
# TODO: Finish rainbow color schemes
rainbow14 = c("3" = "#D1BBD7", "6" = "#AE76A3", "9" = "#882E72", "10" = "#1965B0", "12" = "#5289C7", "14" = "#7BAFDE", "15" = "#4EB265", "16" = "#90C987", "17" = "#CAE0AB", "18" = "#F7F056", "20" = "#F6C141", "22" = "#F1932D", "24" = "#E8601C", "26" = "#DC050C", grey = "#777777"),
rainbow23 = c("1" = "#E8ECFB", "2" = "#D9CCE3", "4" = "#CAACCB", "5" = "#BA8DB4", "7" = "#AA6F9E", "8" = "#994F88", "9" = "#882E72", "10" = "#1965B0", "11" = "#437DBF", "13" = "#6195CF", "14" = "#7BAFDE", "15" = "#4EB265", "16" = "#90C987", "17" = "#CAE0AB", "18" = "#F7F056", "19" = "#F7CB45", "21" = "#F4A736", "23" = "#EE8026", "25" = "#E65518", "26" = "#DC050C", "27" = "#A5170E", "28" = "#72190E", "29" = "#42150A", grey = "#777777"),
rainbow_all = c("1" = "#E8ECFB", "2" = "#D9CCE3", "3" = "#D1BBD7", "4" = "#CAACCB", "5" = "#BA8DB4", "6" = "#AE76A3", "7" = "#AA6F9E", "8" = "#994F88", "9" = "#882E72", "10" = "#1965B0", "11" = "#437DBF", "12" = "#5289C7", "13" = "#6195CF", "14" = "#7BAFDE", "15" = "#4EB265", "16" = "#90C987", "17" = "#CAE0AB", "18" = "#F7F056", "19" = "#F7CB45", "20" = "#F6C141", "21" = "#F4A736", "22" = "#F1932D", "23" = "#EE8026", "24" = "#E8601C", "25" = "#E65518", "26" = "#DC050C", "27" = "#A5170E", "28" = "#72190E", "29" = "#42150A", "grey" = "#777777"),
ground_cover = c(
water = "#5566AA", "evergreen needleleaf forest" = "#117733", "deciduous needleleaf forest" = "#44AA66",
"mixed forest" = "#55AA22", "evergreen broadleaf forest" = "#668822", "deciduous broadleaf forest" = "#88BB55",
woodland = "#558877", "wooded grassland" = "#88BBAA", grassland = "#AADDCC", cropland = "#44AA88",
"closed shrubland" = "#DDCC66", "open shrubland" = "#FFDD44", "bare ground" = "#FFEE88", "urband and built up" = "#BB0011"
)
)

#TODO: Add function for rainbow palettes of 1-23

# TODO: Add smooth palettes
tol_colors_smooth_list <- list(
# Diverging
sunset = NULL,
nightfall = NULL
BuRd = NULL,
PRGn = NULL,
# Sequential
YlOrBr = NULL,
iridescent = NULL,
rainbow = NULL
)


#' Extract Paul Tol colors as hex codes
#'
#' Can be used to get the hex code of specific colors from the Paul Tol palettes.
#' Use `tol_colors()` and specify `palette` to see all available colors.
#' Note that for sequential palettes, only original (non-interpolated) colors are shown.
#'
#' @param ... Character names of colors.
#' @param palette Character name of palette. Can be:
#' - Qualitative: `"bright"`, `"high-contrast"`, `"vibrant"`, `"muted"`,`
#' "medium-contrast"`, `"pale"`, `"dark"`, `"light"`, `"ground_cover"`
#' - Diverging: `"sunset"`, `"nightfall"`, `"BuRd"`, `"PRGn"`
#' - Sequential: `"YlOrBr"`, `"iridescent"`, `"rainbow_discrete"`,
#' `"rainbow_smooth"`
#'
#' @return A character vector with color-codes.
#'
#' @examples
#' tol_colors()
#'
#' tol_colors(c("red", "light blue", "yellow"))
#'
#' tol_colors(palette = "muted")
#'
#' tol_colors(c("red", "light blue", "yellow"), palette = "muted")
#' @export
tol_colors <- function(..., palette = "bright") {
cols <- c(...)

# TODO: Extract Tol palettes instead of O-I
if (!is.null(cols)) {
return(okabeito_colors_list[cols])
}

yellow_col <- if (isTRUE(amber)) "amber" else "yellow"

if (isTRUE(original_names)) {
cols <- c("orange", "sky blue", "bluish green", yellow_col, "blue", "vermillion", "reddish purple", "grey", "black")
} else {
cols <- c("orange", "light blue", "green", yellow_col, "blue", "red", "purple", "grey", "black")
}

if (isTRUE(black_first)) cols <- union("black", cols)

okabeito_colors_list[cols]
}


#' Paul Tol's color palettes
#'
#' The palettes proposed by Tol (2021).
#'
#' @param palette Character name of palette. Can be:
#' - Qualitative: `"bright"`, `"high-contrast"`, `"vibrant"`, `"muted"`,
#' `"medium-contrast"`, `"pale"`, `"dark"`, `"light"`, `"ground_cover"`
#' - Diverging: `"sunset"`, `"nightfall",` `"BuRd"`, `"PRGn"`
#' - Sequential: `"YlOrBr"`, `"iridescent"`, `"rainbow_discrete"`,
#' - `"rainbow_smooth"`
#' @param reverse Boolean indicating whether the palette should be reversed.
#' @param order A vector of numbers indicating the order of colors to use
#' (default: `NULL` indicating to use all available colors in order).
#' @param ... For sequential palettes other than `rainbow_discrete`, additional
#' arguments to pass to [`grDevices::colorRampPalette()`].
#'
#' @references
#' Tol, P. (2021). Colour schemes (SRON/EPS Technical Note No. 09-002; Version 3.2).
#' SRON. https://personal.sron.nl/~pault/data/colourschemes.pdf (Original work published 2009)
#'
#' @details This function is usually not called directly, but from within
#' [`scale_color_tol()`].
#'
#' @export
palette_tol_discrete <- function(palette = "bright", reverse = FALSE, order = NULL, ...) {
if (!palette %in% names(tol_palettes)) {
msg <- c(paste0(
"Palette name not available. `palette` must be one of ",
datawizard::text_concatenate(names(okabeito_palettes), last = " or ", enclose = "`"),
"."
), "Using default palette now.")
insight::format_warning(msg)
palette <- "full"
}

# TODO: Extract Tol palettes instead of O-I
pal <- okabeito_palettes[[palette]]

stopifnot(
"`order` must be a vector of integers." = is.numeric(order),
"All elements of `order` must be greater than 0 and less than 23." = all(order > 0 & order <= 23)
)
pal <- pal[order]

if (reverse) pal <- rev(pal)

function(n) {
if (n > length(pal)) {
insight::format_warning(
"The number of colors requested `n` is too large.",
paste0("The maximum number of colors is ", length(pal), "."),
paste0("Returning a palette with ", length(pal), " colors.")
)
n <- length(pal)
}
unname(pal[seq_len(n)])
}
}
7 changes: 7 additions & 0 deletions inst/WORDLIST
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,12 @@ ORCID
Okabe
Polychoric
Québec
SEM
SRON
Shachar
Tetrachoric
Tol
Tol's
UI
Université
VIF
Expand Down Expand Up @@ -87,6 +91,9 @@ qq
qqplotr
rOpenSci
rstanarm
sjPlot
strengejacke
sron
subfigures
ui
unmapped
Expand Down
Loading
Loading