Maps one of the viridis colour palettes, or a user-specified palette to values. Viridis colour maps are created by Stéfan van der Walt and Nathaniel Smith, and were set as the default palette for the 'Python' 'Matplotlib' library < https://matplotlib.org/>. Other palettes available in this library have been derived from 'RColorBrewer' < https://CRAN.R-project.org/package=RColorBrewer> and 'colorspace' < https://CRAN.R-project.org/package=colorspace> packages.
It maps viridis colours (by default) to values, and quickly!
Note It does not perform a 1-to-1 mapping of a palette to values. It interpolates the colours from a given palette.
I’m aware there are other methods for mapping colours to values. And
which do it quick too. But I can never remember them, and I find the
interfaces a bit cumbersome. For example, scales::col_numeric(palette = viridisLite::viridis(5), domain = range(1:5))(1:5)
.
I wanted one function which will work on one argument.
colour_values(1:5)# [1] "#440154FF" "#3B528BFF" "#21908CFF" "#5DC963FF" "#FDE725FF"colour_values(letters[1:5])# [1] "#440154FF" "#3B528BFF" "#21908CFF" "#5DC963FF" "#FDE725FF"
I also want it available at the src
(C/C++) level for linking to other
packages.
Because it’s correct, and R tells us to
But don’t worry, color_values(1:5)
works as well
From CRAN
install.packages("colourvalues")
Or install the development version from GitHub with:
# install.packages("devtools")devtools::install_github("SymbolixAU/colourvalues")
Rcpp
All functions are written in Rcpp
. I have exposed some of them in
header files so you can “link to” them in your package.
For example, the LinkingTo
section in DESCRIPTION
will look
something like
LinkingTo:Rcpp,colourvalues
And in a c++ source file so you can #include
a header and use the
available functions
// [[Rcpp::depends(colourvalues)]]
R
If you’re not using Rcpp
, just Import
this package like you would
any other.
Of course!
bar_plot <- function(df) {barplot( height = df[["a"]], col = df[["col"]], border = NA, space = 0, yaxt = 'n')}df <- data.frame(a = 10, x = 1:256)df$col <- colour_values(df$x, palette = "viridis")bar_plot( df )
df <- data.frame(a = 10, x = c((1:5000)**3))df$col <- colour_values(df$x, palette = "viridis")bar_plot( df )
df <- data.frame(a = 10, x = rnorm(n = 1000))df$col <- colour_values(df$x, palette = "inferno")bar_plot( df )
Eurgh!
df <- df[with(df, order(x)), ]bar_plot( df )
That’s better!
No, you can chose one from
colour_palettes()# [1] "viridis" "cividis" "magma" "inferno"# [5] "plasma" "ylorrd" "ylorbr" "ylgnbu"# [9] "ylgn" "reds" "rdpu" "purples"# [13] "purd" "pubugn" "pubu" "orrd"# [17] "oranges" "greys" "greens" "gnbu"# [21] "bupu" "bugn" "blues" "spectral"# [25] "rdylgn" "rdylbu" "rdgy" "rdbu"# [29] "puor" "prgn" "piyg" "brbg"# [33] "terrain" "topo" "heat" "cm"# [37] "rainbow" "terrain_hcl" "heat_hcl" "sequential_hcl"# [41] "rainbow_hcl" "diverge_hcl" "diverge_hsv" "ygobb"# [45] "matlab_like2" "matlab_like" "magenta2green" "cyan2yellow"# [49] "blue2yellow" "green2red" "blue2green" "blue2red"
And you can use show_colours()
to view them all. Here’s what some of
them look
like
show_colours( colours = colour_palettes(c("viridis", "colorspace")))
No, you can use your own specified as a matrix of red, green and blue columns in the range [0,255]
n <- 100m <- grDevices::colorRamp(c("red", "green"))( (1:n)/n )df <- data.frame(a = 10, x = 1:n)df$col <- colour_values(df$x, palette = m)bar_plot( df )
Yep. Either supply a single alpha value for all the colours
## single alpha value for all coloursdf <- data.frame(a = 10, x = 1:255)df$col <- colour_values(df$x, alpha = 50)bar_plot( df )
Or use a vector of values the same length as x
df <- data.frame(a = 10, x = 1:300, y = rep(c(1:50, 50:1), 3) )df$col <- colour_values(df$x, alpha = df$y)bar_plot( df )
Or include the alpha value as a 4th column in the palette matrix
n <- 100m <- grDevices::colorRamp(c("red", "green"))( (1:n)/n )## alpha valuesm <- cbind(m, seq(0, 255, length.out = 100))df <- data.frame(a = 10, x = 1:n)df$col <- colour_values(df$x, palette = m)bar_plot( df )
Yep. Set include_alpha = FALSE
colour_values(1:5, include_alpha = F)# [1] "#440154" "#3B528B" "#21908C" "#5DC963" "#FDE725"colour_values_rgb(1:5, include_alpha = F)# [,1] [,2] [,3]# [1,] 68 1 84# [2,] 59 82 139# [3,] 33 144 140# [4,] 93 201 99# [5,] 253 231 37
Yes, for numeric values use the n_summaries
argument to specify the
number of summary values you’d like
colour_values(1:10, n_summaries = 3)# $colours# [1] "#440154FF" "#482878FF" "#3E4A89FF" "#31688EFF" "#26838EFF"# [6] "#1F9D89FF" "#35B779FF" "#6CCE59FF" "#B4DD2CFF" "#FDE725FF"## $summary_values# [1] "1.00" "5.50" "10.00"## $summary_colours# [1] "#440154FF" "#21908CFF" "#FDE725FF"
You can also specify the number of digits you’d like returned in the summary
colour_values(rnorm(n = 10), n_summaries = 3, digits = 2)# $colours# [1] "#27AD81FF" "#3F4989FF" "#39568CFF" "#218F8DFF" "#228C8DFF"# [6] "#FDE725FF" "#440154FF" "#3F4889FF" "#453681FF" "#26818EFF"## $summary_values# [1] "-1.21" "0.71" "2.62"## $summary_colours# [1] "#440154FF" "#21908CFF" "#FDE725FF"
You can also use format = FALSE
if you don’t want the summary values
formatted.
dte <- seq(as.Date("2018-01-01"), as.Date("2018-02-01"), by = 1)colour_values(dte, n_summaries = 3)# $colours# [1] "#440154FF" "#470D60FF" "#48196BFF" "#482474FF" "#472E7CFF"# [6] "#453882FF" "#414286FF" "#3E4B8AFF" "#3A548CFF" "#365D8DFF"# [11] "#32658EFF" "#2E6D8EFF" "#2B758EFF" "#287D8EFF" "#25858EFF"# [16] "#228C8DFF" "#20948CFF" "#1E9C89FF" "#20A386FF" "#25AB82FF"# [21] "#2DB27DFF" "#39BA76FF" "#48C16EFF" "#58C765FF" "#6ACD5BFF"# [26] "#7ED34FFF" "#92D742FF" "#A8DB34FF" "#BEDF26FF" "#D4E21BFF"# [31] "#E9E41AFF" "#FDE725FF"## $summary_values# [1] "2018-01-01" "2018-01-16" "2018-02-01"## $summary_colours# [1] "#440154FF" "#21908CFF" "#FDE725FF"colour_values(dte, n_summaries = 3, format = F)# $colours# [1] "#440154FF" "#470D60FF" "#48196BFF" "#482474FF" "#472E7CFF"# [6] "#453882FF" "#414286FF" "#3E4B8AFF" "#3A548CFF" "#365D8DFF"# [11] "#32658EFF" "#2E6D8EFF" "#2B758EFF" "#287D8EFF" "#25858EFF"# [16] "#228C8DFF" "#20948CFF" "#1E9C89FF" "#20A386FF" "#25AB82FF"# [21] "#2DB27DFF" "#39BA76FF" "#48C16EFF" "#58C765FF" "#6ACD5BFF"# [26] "#7ED34FFF" "#92D742FF" "#A8DB34FF" "#BEDF26FF" "#D4E21BFF"# [31] "#E9E41AFF" "#FDE725FF"## $summary_values# [1] 17532.0 17547.5 17563.0## $summary_colours# [1] "#440154FF" "#21908CFF" "#FDE725FF"
For categorical values use summary = TRUE
to return a uniqe set of the
values, and their associated colours
colour_values(sample(letters, size = 50, replace = T), summary = T)# $colours# [1] "#2F6C8EFF" "#2FB47CFF" "#482575FF" "#2F6C8EFF" "#43BF71FF"# [6] "#3B528BFF" "#414487FF" "#2FB47CFF" "#43BF71FF" "#5DC963FF"# [11] "#5DC963FF" "#2F6C8EFF" "#7AD151FF" "#345F8DFF" "#7AD151FF"# [16] "#7AD151FF" "#482575FF" "#25848EFF" "#1E9C89FF" "#2A788EFF"# [21] "#9AD93DFF" "#3B528BFF" "#481466FF" "#7AD151FF" "#22A884FF"# [26] "#5DC963FF" "#21908CFF" "#FDE725FF" "#21908CFF" "#DDE318FF"# [31] "#463480FF" "#21908CFF" "#25848EFF" "#2F6C8EFF" "#481466FF"# [36] "#25848EFF" "#440154FF" "#BCDF27FF" "#345F8DFF" "#25848EFF"# [41] "#440154FF" "#FDE725FF" "#440154FF" "#43BF71FF" "#1E9C89FF"# [46] "#22A884FF" "#2F6C8EFF" "#BCDF27FF" "#DDE318FF" "#463480FF"## $summary_values# [1] "a" "b" "c" "e" "f" "g" "h" "i" "j" "k" "m" "o" "p" "q" "r" "s" "t"# [18] "u" "x" "y" "z"## $summary_colours# [1] "#440154FF" "#481466FF" "#482575FF" "#463480FF" "#414487FF"# [6] "#3B528BFF" "#345F8DFF" "#2F6C8EFF" "#2A788EFF" "#25848EFF"# [11] "#21908CFF" "#1E9C89FF" "#22A884FF" "#2FB47CFF" "#43BF71FF"# [16] "#5DC963FF" "#7AD151FF" "#9AD93DFF" "#BCDF27FF" "#DDE318FF"# [21] "#FDE725FF"
10 million numeric values
library(microbenchmark)library(ggplot2)library(scales)library(viridisLite)n <- 1e7df <- data.frame(x = rnorm(n = n))m <- microbenchmark(colourvalues = { colourvalues::colour_values(x = df$x) },scales = { col_numeric(palette = rgb(subset(viridis.map, opt=="D")[, 1:3]), domain = range(df$x))(df$x) },times = 25)m# Unit: seconds# expr min lq mean median uq max neval# colourvalues 1.617036 1.629365 1.682938 1.645191 1.745641 1.800155 25# scales 2.820961 2.916128 3.035900 2.981311 3.140706 3.418156 25autoplot(m)# Coordinate system already present. Adding new coordinate system, which will replace the existing one.
1 million characters (26 unique values)
library(microbenchmark)library(ggplot2)library(scales)library(viridisLite)n <- 1e6x <- sample(x = letters, size = n, replace = TRUE)df <- data.frame(x = x)m <- microbenchmark(colourvalues = { x <- colourvalues::colour_values(x = df$x) },scales = { y <- col_factor(palette = rgb(subset(viridis.map, opt=="D")[, 1:3]), domain = unique(df$x))(df$x) },times = 25)m# Unit: milliseconds# expr min lq mean median uq max neval# colourvalues 182.1952 203.5807 206.2559 207.5844 209.7223 245.3349 25# scales 329.7487 342.8897 349.5171 345.3121 345.8927 417.3716 25autoplot(m)# Coordinate system already present. Adding new coordinate system, which will replace the existing one.
show_colours()
to plot all colour palettescolour_palettes()
to list themalpha
can accept [0,1) values to indicate a percentageformat
, summary
, n_summaries
arguments for returning summary colours (for use in legends)convert_colours()
function exposed to R to convert between hex-rgb issue 14NumericVector
s issue 26inline
statementsNEWS.md
file to track changes to the package.