From e4a7485563b5feb5d32608ee73140fa0982d038a Mon Sep 17 00:00:00 2001 From: Carl Suster Date: Fri, 3 Apr 2026 12:50:32 +1100 Subject: [PATCH] Add col_contrasting --- NAMESPACE | 1 + R/colour-manip.R | 22 ++++++++++++++++++ man/alpha.Rd | 1 + man/col2hcl.Rd | 1 + man/col_contrasting.Rd | 36 ++++++++++++++++++++++++++++++ man/col_mix.Rd | 1 + man/colour_manip.Rd | 1 + man/muted.Rd | 1 + tests/testthat/test-colour-manip.R | 7 ++++++ 9 files changed, 71 insertions(+) create mode 100644 man/col_contrasting.Rd diff --git a/NAMESPACE b/NAMESPACE index 0d4b5af3..a314a36f 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -76,6 +76,7 @@ export(cbreaks) export(censor) export(col2hcl) export(col_bin) +export(col_contrasting) export(col_darker) export(col_factor) export(col_lighter) diff --git a/R/colour-manip.R b/R/colour-manip.R index 102ac6bf..11e47bcd 100644 --- a/R/colour-manip.R +++ b/R/colour-manip.R @@ -177,6 +177,28 @@ col_mix.scales_pal <- function(a, b, amount = 0.5, space = "rgb") { wrap_col_adjustment(a, col_mix, list(b = b, amount = amount, space = space)) } +#' Choose a contrasting colour +#' +#' Chooses either `light` or `dark` based on the lightness of `colour`. +#' This is useful for choosing a text colour that is legible on a solid background +#' cooured with `colour`. +#' +#' @param colour character vector of colours to be modified +#' @param light colour to return when `colour` is dark +#' @param dark colour to return when `colour` is light +#' +#' @return A character vector of colours with the same length as `colour` +#' @family colour manipulation +#' @export +#' +#' @examples +#' col_contrasting(c("navy", "white", "black", "yellow")) +#' +col_contrasting <- function(colour, light = "white", dark = "black") { + lab <- farver::decode_colour(colour, to = "lab") + ifelse(lab[, 1] < 50, light, dark) +} + #' Colour manipulation #' #' These are a set of convenience functions for standard colour manipulation diff --git a/man/alpha.Rd b/man/alpha.Rd index 8b2d40c8..add70090 100644 --- a/man/alpha.Rd +++ b/man/alpha.Rd @@ -24,6 +24,7 @@ alpha(c("first" = "gold", "second" = "lightgray", "third" = "#cd7f32"), .5) \seealso{ Other colour manipulation: \code{\link{col2hcl}()}, +\code{\link{col_contrasting}()}, \code{\link{col_mix}()}, \code{\link{colour_manip}}, \code{\link{muted}()} diff --git a/man/col2hcl.Rd b/man/col2hcl.Rd index 6e339cd3..9c47ae7d 100644 --- a/man/col2hcl.Rd +++ b/man/col2hcl.Rd @@ -31,6 +31,7 @@ show_col(col2hcl(reds, alpha = seq(0, 1, length = 6))) \seealso{ Other colour manipulation: \code{\link{alpha}()}, +\code{\link{col_contrasting}()}, \code{\link{col_mix}()}, \code{\link{colour_manip}}, \code{\link{muted}()} diff --git a/man/col_contrasting.Rd b/man/col_contrasting.Rd new file mode 100644 index 00000000..a6b2e381 --- /dev/null +++ b/man/col_contrasting.Rd @@ -0,0 +1,36 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/colour-manip.R +\name{col_contrasting} +\alias{col_contrasting} +\title{Choose a contrasting colour} +\usage{ +col_contrasting(colour, light = "white", dark = "black") +} +\arguments{ +\item{colour}{character vector of colours to be modified} + +\item{light}{colour to return when \code{colour} is dark} + +\item{dark}{colour to return when \code{colour} is light} +} +\value{ +A character vector of colours with the same length as \code{colour} +} +\description{ +Chooses either \code{light} or \code{dark} based on the lightness of \code{colour}. +This is useful for choosing a text colour that is legible on a solid background +cooured with \code{colour}. +} +\examples{ +col_contrasting(c("navy", "white", "black", "yellow")) + +} +\seealso{ +Other colour manipulation: +\code{\link{alpha}()}, +\code{\link{col2hcl}()}, +\code{\link{col_mix}()}, +\code{\link{colour_manip}}, +\code{\link{muted}()} +} +\concept{colour manipulation} diff --git a/man/col_mix.Rd b/man/col_mix.Rd index f5181402..f0264d13 100644 --- a/man/col_mix.Rd +++ b/man/col_mix.Rd @@ -35,6 +35,7 @@ col_mix("blue", "red", space = "hcl") # green! Other colour manipulation: \code{\link{alpha}()}, \code{\link{col2hcl}()}, +\code{\link{col_contrasting}()}, \code{\link{colour_manip}}, \code{\link{muted}()} } diff --git a/man/colour_manip.Rd b/man/colour_manip.Rd index ff023c69..080e3ec2 100644 --- a/man/colour_manip.Rd +++ b/man/colour_manip.Rd @@ -51,6 +51,7 @@ col_saturate("red", -50) # brick-red Other colour manipulation: \code{\link{alpha}()}, \code{\link{col2hcl}()}, +\code{\link{col_contrasting}()}, \code{\link{col_mix}()}, \code{\link{muted}()} } diff --git a/man/muted.Rd b/man/muted.Rd index ffaa5def..20061d27 100644 --- a/man/muted.Rd +++ b/man/muted.Rd @@ -25,6 +25,7 @@ show_col(c("red", "blue", muted("red"), muted("blue"))) Other colour manipulation: \code{\link{alpha}()}, \code{\link{col2hcl}()}, +\code{\link{col_contrasting}()}, \code{\link{col_mix}()}, \code{\link{colour_manip}} } diff --git a/tests/testthat/test-colour-manip.R b/tests/testthat/test-colour-manip.R index 2108801e..a26dad8e 100644 --- a/tests/testthat/test-colour-manip.R +++ b/tests/testthat/test-colour-manip.R @@ -84,3 +84,10 @@ test_that("colour manipulation functions work on palettes", { expect_equal(col_saturate(pal, -50)(3), c("#BF4040", "#40BF40", "#4040BF")) expect_equal(col_mix(pal, "white")(3), c("#FF8080", "#80FF80", "#8080FF")) }) + +# col_contrasting ------------------------------------------------ + +test_that("col_contrasting chooses suitable colours", { + colours <- c("navy", "white", "black", "yellow") + expect_equal(col_contrasting(colours), c("white", "black", "white", "black")) +})