Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Map values to viridis colours in r

Tags:

r

How do I create a colour scale function in r with a pre-defined scale (like viridis from library("viridis")?

The question is not how to use it within ggplot, but how to build a function I can feed arbitrary values within the specified value domain to and retrieve the according colour strings (rgb, hex or any other output format) from.

colorRamp and colorRampPalette seem to interpolate only between 2 colours within a given colour space. But how would I go about this with viridis for example?

EDIT:

Thanks to @sconfluentus' answer I wrote the following function that does what I want (w/o safety checks):

library("viridis")

number_vector <- c(0.772, 1.235, 5.78, 8.890, 10.543, 14.702)

map_viridis <- function(vec, num) {

  vector_expanded <-round(vec, 1) * 10 # expand to allow for decimal precision
  vector_exp_range <- max(vector_expanded) - min(vector_expanded)

  colour_vector <- viridis(vector_exp_range + 1) # get vector of colour values for all possible decimals between min and max value
  value_to_colour <- colour_vector[num * 10 - min(vector_expanded) + 1] # retrieve colour value for number

  return(value_to_colour)

}

map_viridis(number_vector, 0.8) # returns "#440154FF"
map_viridis(number_vector, 3.4) # returns "#424086FF"
map_viridis(number_vector, 14.7) # returns "#FDE725FF"

Just wondering if there's not a more direct way to achieve this result?

like image 285
lve Avatar asked Aug 13 '17 17:08

lve


Video Answer


1 Answers

Viridis itself is capable creating the values you are looking for provided you use it correctly in your own function and you know how many arbitrary values will be created.

viridis(12)
 [1] "#440154FF" "#482173FF" "#433E85FF" "#38598CFF" "#2D708EFF" "#25858EFF" "#1E9B8AFF"
 [8] "#2BB07FFF" "#51C56AFF" "#85D54AFF" "#C2DF23FF" "#FDE725FF"

So you could create a function which takes your domain, calculates the length of values in it and then creates a series of colors for each manipulating your data any way you choose. The basis for it would be like this

num_vals=length(x) # substitute nrow  for length if you have rows instead of a list
col_pal = viridis(num_vals)

As long as the set is ordered then you can simply use data[1] and col_pal[1] to associate them in pairs..or you could create a list of pairs and colors depending on how you choose to substitute them into your function.

or you could create a ramp with colorRampPalette as such

map_colors<-colorRampPalette(viridis(12)) # this would create 12 viridis colors
like image 173
sconfluentus Avatar answered Sep 22 '22 12:09

sconfluentus