1#' Binned gradient colour scales
2#'
3#' `scale_*_steps` creates a two colour binned gradient (low-high),
4#' `scale_*_steps2` creates a diverging binned colour gradient (low-mid-high),
5#' and `scale_*_stepsn` creates a n-colour binned gradient. These scales are
6#' binned variants of the [gradient scale][scale_colour_gradient] family and
7#' works in the same way.
8#'
9#' Default colours are generated with \pkg{munsell} and
10#' `mnsl(c("2.5PB 2/4", "2.5PB 7/10"))`. Generally, for continuous
11#' colour scales you want to keep hue constant, but vary chroma and
12#' luminance. The \pkg{munsell} package makes this easy to do using the
13#' Munsell colour system.
14#'
15#' @inheritParams scale_colour_gradient
16#' @inheritDotParams binned_scale -aesthetics -scale_name -palette -na.value -guide -rescaler
17#'
18#' @seealso [scales::seq_gradient_pal()] for details on underlying
19#'   palette, [scale_colour_gradient()] for continuous scales without binning.
20#' @family colour scales
21#' @export
22#' @examples
23#' df <- data.frame(
24#'   x = runif(100),
25#'   y = runif(100),
26#'   z1 = rnorm(100)
27#' )
28#'
29#' # Use scale_colour_steps for a standard binned gradient
30#' ggplot(df, aes(x, y)) +
31#'   geom_point(aes(colour = z1)) +
32#'   scale_colour_steps()
33#'
34#' # Get a divergent binned scale with the *2 variant
35#' ggplot(df, aes(x, y)) +
36#'   geom_point(aes(colour = z1)) +
37#'   scale_colour_steps2()
38#'
39#' # Define your own colour ramp to extract binned colours from
40#' ggplot(df, aes(x, y)) +
41#'   geom_point(aes(colour = z1)) +
42#'   scale_colour_stepsn(colours = terrain.colors(10))
43#' @rdname scale_steps
44scale_colour_steps <- function(..., low = "#132B43", high = "#56B1F7", space = "Lab",
45                               na.value = "grey50", guide = "coloursteps", aesthetics = "colour") {
46  binned_scale(aesthetics, "steps", seq_gradient_pal(low, high, space),
47               na.value = na.value, guide = guide, ...)
48}
49#' @rdname scale_steps
50#' @export
51scale_colour_steps2 <- function(..., low = muted("red"), mid = "white", high = muted("blue"),
52                                midpoint = 0, space = "Lab", na.value = "grey50", guide = "coloursteps",
53                                aesthetics = "colour") {
54  binned_scale(aesthetics, "steps2", div_gradient_pal(low, mid, high, space),
55               na.value = na.value, guide = guide, rescaler = mid_rescaler(mid = midpoint), ...)
56}
57#' @rdname scale_steps
58#' @export
59scale_colour_stepsn <- function(..., colours, values = NULL, space = "Lab", na.value = "grey50",
60                                guide = "coloursteps", aesthetics = "colour", colors) {
61  colours <- if (missing(colours)) colors else colours
62  binned_scale(aesthetics, "stepsn",
63               gradient_n_pal(colours, values, space), na.value = na.value, guide = guide, ...)
64}
65#' @rdname scale_steps
66#' @export
67scale_fill_steps <- function(..., low = "#132B43", high = "#56B1F7", space = "Lab",
68                             na.value = "grey50", guide = "coloursteps", aesthetics = "fill") {
69  binned_scale(aesthetics, "steps", seq_gradient_pal(low, high, space),
70               na.value = na.value, guide = guide, ...)
71}
72#' @rdname scale_steps
73#' @export
74scale_fill_steps2 <- function(..., low = muted("red"), mid = "white", high = muted("blue"),
75                              midpoint = 0, space = "Lab", na.value = "grey50", guide = "coloursteps",
76                              aesthetics = "fill") {
77  binned_scale(aesthetics, "steps2", div_gradient_pal(low, mid, high, space),
78               na.value = na.value, guide = guide, rescaler = mid_rescaler(mid = midpoint), ...)
79}
80#' @rdname scale_steps
81#' @export
82scale_fill_stepsn <- function(..., colours, values = NULL, space = "Lab", na.value = "grey50",
83                                guide = "coloursteps", aesthetics = "fill", colors) {
84  colours <- if (missing(colours)) colors else colours
85  binned_scale(aesthetics, "stepsn",
86               gradient_n_pal(colours, values, space), na.value = na.value, guide = guide, ...)
87}
88