|
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,119 @@ 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 | +#' Colour scales for discrete data default to the values of the `ggplot2.discrete.fill` |
| 70 | +#' and `ggplot2.discrete.colour` options. By default these scales attempt to use |
| 71 | +#' a colour-blind safe (or a custom) palette, but if the number of levels is |
| 72 | +#' large, they fallback to [scale_fill_hue()]/[scale_colour_hue()]. |
| 73 | +#' |
| 74 | +#' @param ... Additional parameters passed on to the scale type, |
| 75 | +#' @param type One of the following: |
| 76 | +#' * A character vector of color codes. The codes are used for a 'manual' color |
| 77 | +#' scale as long as the number of codes exceeds the number of data levels |
| 78 | +#' (if there are more levels than codes, [scale_colour_hue()]/[scale_fill_hue()] |
| 79 | +#' are used to construct the default scale). |
| 80 | +#' * A list of character vectors of color codes. The minimum length vector that exceeds the |
| 81 | +#' number of data levels is chosen for the color scaling. This is useful if you |
| 82 | +#' want to change the color palette based on the number of levels. |
| 83 | +#' * A function that returns a discrete colour/fill scale (e.g., [scale_fill_hue()], |
| 84 | +#' [scale_fill_brewer()], etc). |
| 85 | +#' @export |
| 86 | +#' @rdname |
| 87 | +#' @examples |
| 88 | +#' # Template function for creating densities grouped by a variable |
| 89 | +#' cty_by_var <- function(var) { |
| 90 | +#' ggplot(mpg, aes(cty, colour = factor({{var}}), fill = factor({{var}}))) + |
| 91 | +#' geom_density(alpha = 0.2) |
| 92 | +#' } |
| 93 | +#' # The default color scale for three levels |
| 94 | +#' cty_by_var(class) |
| 95 | +#' |
| 96 | +#' # Define custom palettes for when there are 1-2, 3, or 4-6 levels |
| 97 | +#' opts <- options( |
| 98 | +#' ggplot2.discrete.fill = list( |
| 99 | +#' c("skyblue", "orange"), |
| 100 | +#' RColorBrewer::brewer.pal(3, "Set2"), |
| 101 | +#' RColorBrewer::brewer.pal(6, "Accent") |
| 102 | +#' ) |
| 103 | +#' ) |
| 104 | +#' cty_by_var(year) |
| 105 | +#' cty_by_var(drv) |
| 106 | +#' cty_by_var(fl) |
| 107 | +#' cty_by_var(class) |
| 108 | +#' options(opts) |
| 109 | +#' |
| 110 | +scale_colour_discrete <- function(..., type = getOption("ggplot2.discrete.colour", getOption("ggplot2.discrete.fill"))) { |
| 111 | + type <- type %||% okabeIto |
| 112 | + if (is.function(type)) { |
| 113 | + type(...) |
| 114 | + } else { |
| 115 | + scale_colour_qualitative(..., codes = type) |
| 116 | + } |
| 117 | +} |
| 118 | + |
| 119 | +#' @rdname scale_colour_discrete |
| 120 | +#' @export |
| 121 | +scale_fill_discrete <- function(..., type = getOption("ggplot2.discrete.fill", getOption("ggplot2.discrete.colour"))) { |
| 122 | + type <- type %||% okabeIto |
| 123 | + if (is.function(type)) { |
| 124 | + type(...) |
| 125 | + } else { |
| 126 | + scale_fill_qualitative(..., codes = type) |
| 127 | + } |
| 128 | +} |
| 129 | + |
| 130 | +scale_colour_qualitative <- function(..., codes = NULL, h = c(0, 360) + 15, c = 100, l = 65, h.start = 0, |
| 131 | + direction = 1, na.value = "grey50", aesthetics = "colour") { |
| 132 | + discrete_scale( |
| 133 | + aesthetics, "qualitative", qualitative_pal(codes, h, c, l, h.start, direction), |
| 134 | + na.value = na.value, ... |
| 135 | + ) |
| 136 | +} |
| 137 | + |
| 138 | +scale_fill_qualitative <- function(..., codes = NULL, h = c(0, 360) + 15, c = 100, l = 65, h.start = 0, |
| 139 | + direction = 1, na.value = "grey50", aesthetics = "fill") { |
| 140 | + discrete_scale( |
| 141 | + aesthetics, "qualitative", qualitative_pal(codes, h, c, l, h.start, direction), |
| 142 | + na.value = na.value, ... |
| 143 | + ) |
| 144 | +} |
| 145 | + |
| 146 | +qualitative_pal <- function(codes, h, c, l, h.start, direction) { |
| 147 | + function(n) { |
| 148 | + if (!length(codes)) { |
| 149 | + return(scales::hue_pal(h, c, l, h.start, direction)(n)) |
| 150 | + } |
| 151 | + codes_list <- if (!is.list(codes)) list(codes) else codes |
| 152 | + if (!all(vapply(codes_list, is.character, logical(1)))) { |
| 153 | + stop("codes must be a character vector or a list of character vectors", call. = FALSE) |
| 154 | + } |
| 155 | + codes_lengths <- vapply(codes_list, length, integer(1)) |
| 156 | + # If there are more levels than color codes default to hue_pal() |
| 157 | + if (max(codes_lengths) < n) { |
| 158 | + return(scales::hue_pal(h, c, l, h.start, direction)(n)) |
| 159 | + } |
| 160 | + # Use the minimum length vector that exceeds the number of levels (n) |
| 161 | + codes_list <- codes_list[order(codes_lengths)] |
| 162 | + i <- 1 |
| 163 | + while (length(codes_list[[i]]) < n) { |
| 164 | + i <- i + 1 |
| 165 | + } |
| 166 | + codes_list[[i]][seq_len(n)] |
| 167 | + } |
| 168 | +} |
| 169 | + |
| 170 | +# prismatic::check_color_blindness(okabeIto) |
| 171 | +okabeIto <- c( |
| 172 | + "#E69F00", |
| 173 | + "#56B4E9", |
| 174 | + "#009E73", |
| 175 | + "#F0E442", |
| 176 | + "#0072B2", |
| 177 | + "#D55E00", |
| 178 | + "#CC79A7", |
| 179 | + "black" |
| 180 | +) |
0 commit comments