|
1 | 1 | #' Evenly spaced colours for discrete data
|
2 | 2 | #'
|
3 |
| -#' This is the default colour scale for categorical variables. It maps each |
4 |
| -#' level to an evenly spaced hue on the colour wheel. It does not generate |
5 |
| -#' colour-blind safe palettes. |
| 3 | +#' Maps each level to an evenly spaced hue on the colour wheel. |
| 4 | +#' It does not generate colour-blind safe palettes. |
6 | 5 | #'
|
7 | 6 | #' @param na.value Colour to use for missing values
|
8 | 7 | #' @inheritDotParams discrete_scale -aesthetics
|
@@ -63,3 +62,118 @@ scale_fill_hue <- function(..., h = c(0, 360) + 15, c = 100, l = 65, h.start = 0
|
63 | 62 | discrete_scale(aesthetics, "hue", hue_pal(h, c, l, h.start, direction),
|
64 | 63 | na.value = na.value, ...)
|
65 | 64 | }
|
| 65 | + |
| 66 | + |
| 67 | +#' Discrete colour scales |
| 68 | +#' |
| 69 | +#' The default discrete colour scale. Defaults to [scale_fill_hue()]/[scale_fill_brewer()] |
| 70 | +#' unless `type` (which defaults to the `ggplot2.discrete.fill`/`ggplot2.discrete.colour` options) |
| 71 | +#' is specified. |
| 72 | +#' |
| 73 | +#' @param ... Additional parameters passed on to the scale type, |
| 74 | +#' @param type One of the following: |
| 75 | +#' * A character vector of color codes. The codes are used for a 'manual' color |
| 76 | +#' scale as long as the number of codes exceeds the number of data levels |
| 77 | +#' (if there are more levels than codes, [scale_colour_hue()]/[scale_fill_hue()] |
| 78 | +#' are used to construct the default scale). |
| 79 | +#' * A list of character vectors of color codes. The minimum length vector that exceeds the |
| 80 | +#' number of data levels is chosen for the color scaling. This is useful if you |
| 81 | +#' want to change the color palette based on the number of levels. |
| 82 | +#' * A function that returns a discrete colour/fill scale (e.g., [scale_fill_hue()], |
| 83 | +#' [scale_fill_brewer()], etc). |
| 84 | +#' @export |
| 85 | +#' @rdname |
| 86 | +#' @examples |
| 87 | +#' # Template function for creating densities grouped by a variable |
| 88 | +#' cty_by_var <- function(var) { |
| 89 | +#' ggplot(mpg, aes(cty, colour = factor({{var}}), fill = factor({{var}}))) + |
| 90 | +#' geom_density(alpha = 0.2) |
| 91 | +#' } |
| 92 | +#' |
| 93 | +#' # The default, scale_fill_hue(), is not colour-blind safe |
| 94 | +#' cty_by_var(class) |
| 95 | +#' |
| 96 | +#' # (Temporarily) set the default to Okabe-Ito (which is colour-blind safe) |
| 97 | +#' okabe <- c("#E69F00", "#56B4E9", "#009E73", "#F0E442", "#0072B2", "#D55E00", "#CC79A7") |
| 98 | +#' withr::with_options( |
| 99 | +#' list(ggplot2.discrete.fill = okabe), |
| 100 | +#' print(cty_by_var(class)) |
| 101 | +#' ) |
| 102 | +#' |
| 103 | +#' # Define a collection of palettes to alter the default based on number of levels to encode |
| 104 | +#' discrete_palettes <- list( |
| 105 | +#' c("skyblue", "orange"), |
| 106 | +#' RColorBrewer::brewer.pal(3, "Set2"), |
| 107 | +#' RColorBrewer::brewer.pal(6, "Accent") |
| 108 | +#' ) |
| 109 | +#' withr::with_options( |
| 110 | +#' list(ggplot2.discrete.fill = discrete_palettes), { |
| 111 | +#' # 1st palette is used when there 1-2 levels (e.g., year) |
| 112 | +#' print(cty_by_var(year)) |
| 113 | +#' # 2nd palette is used when there are 3 levels |
| 114 | +#' print(cty_by_var(drv)) |
| 115 | +#' # 3rd palette is used when there are 4-6 levels |
| 116 | +#' print(cty_by_var(fl)) |
| 117 | +#' }) |
| 118 | +#' |
| 119 | +scale_colour_discrete <- function(..., type = getOption("ggplot2.discrete.colour", getOption("ggplot2.discrete.fill"))) { |
| 120 | + # TODO: eventually `type` should default to a set of colour-blind safe color codes (e.g. Okabe-Ito) |
| 121 | + type <- type %||% scale_colour_hue |
| 122 | + if (is.function(type)) { |
| 123 | + type(...) |
| 124 | + } else { |
| 125 | + scale_colour_qualitative(..., type = type) |
| 126 | + } |
| 127 | +} |
| 128 | + |
| 129 | +#' @rdname scale_colour_discrete |
| 130 | +#' @export |
| 131 | +scale_fill_discrete <- function(..., type = getOption("ggplot2.discrete.fill", getOption("ggplot2.discrete.colour"))) { |
| 132 | + # TODO: eventually `type` should default to a set of colour-blind safe color codes (e.g. Okabe-Ito) |
| 133 | + type <- type %||% scale_fill_hue |
| 134 | + if (is.function(type)) { |
| 135 | + type(...) |
| 136 | + } else { |
| 137 | + scale_fill_qualitative(..., type = type) |
| 138 | + } |
| 139 | +} |
| 140 | + |
| 141 | +scale_colour_qualitative <- function(..., type = NULL, h = c(0, 360) + 15, c = 100, l = 65, h.start = 0, |
| 142 | + direction = 1, na.value = "grey50", aesthetics = "colour") { |
| 143 | + discrete_scale( |
| 144 | + aesthetics, "qualitative", qualitative_pal(type, h, c, l, h.start, direction), |
| 145 | + na.value = na.value, ... |
| 146 | + ) |
| 147 | +} |
| 148 | + |
| 149 | +scale_fill_qualitative <- function(..., type = NULL, h = c(0, 360) + 15, c = 100, l = 65, h.start = 0, |
| 150 | + direction = 1, na.value = "grey50", aesthetics = "fill") { |
| 151 | + discrete_scale( |
| 152 | + aesthetics, "qualitative", qualitative_pal(type, h, c, l, h.start, direction), |
| 153 | + na.value = na.value, ... |
| 154 | + ) |
| 155 | +} |
| 156 | + |
| 157 | +#' Given set(s) of colour codes (i.e., type), find the smallest set that can support n levels |
| 158 | +#' @param type a character vector or a list of character vectors |
| 159 | +#' @noRd |
| 160 | +qualitative_pal <- function(type, h, c, l, h.start, direction) { |
| 161 | + function(n) { |
| 162 | + type_list <- if (!is.list(type)) list(type) else type |
| 163 | + if (!all(vapply(type_list, is.character, logical(1)))) { |
| 164 | + abort("`type` must be a character vector or a list of character vectors", call. = FALSE) |
| 165 | + } |
| 166 | + type_lengths <- vapply(type_list, length, integer(1)) |
| 167 | + # If there are more levels than color codes default to hue_pal() |
| 168 | + if (max(type_lengths) < n) { |
| 169 | + return(scales::hue_pal(h, c, l, h.start, direction)(n)) |
| 170 | + } |
| 171 | + # Use the minimum length vector that exceeds the number of levels (n) |
| 172 | + type_list <- type_list[order(type_lengths)] |
| 173 | + i <- 1 |
| 174 | + while (length(type_list[[i]]) < n) { |
| 175 | + i <- i + 1 |
| 176 | + } |
| 177 | + type_list[[i]][seq_len(n)] |
| 178 | + } |
| 179 | +} |
0 commit comments