1

I have a list of numbers between 0 and 1 and would like to map them to HEX color values using the algorithm provided by scale_color_gradient2. The default color values of low = muted("red"), mid = "white", high = muted("blue") work just fine. I need the HEX values themselves instead of coloring objects on a plot.

A similar question using matplotlib in python as been asked here, but I need to do this in R.

saladi
  • 3,103
  • 6
  • 36
  • 61
  • Please [provide a reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example). – M-- Oct 05 '17 at 19:28
  • It's easier to help if you provide a [reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) with sample input data and the desired output. That way we can test possible solutions. (Notice the other question gave sample data.) It's easier to answer a specific question that can generalize rather than a general question that has no specifics. There are infinitely many ways to map the numbers from 0 to 1 to a color. Is this specifically about replicating the algorithm in `scale_color_gradient2`? – MrFlick Oct 05 '17 at 19:48

2 Answers2

3

The scale_color_gradient2 function uses coloring functions from the scales library. You can get a transformation function with

library(scales)
trans <- div_gradient_pal(muted("red"), mid="white", high=muted("blue"), space="Lab")

And then apply this function to your numbers

cols <- trans(seq(0,1, length.out=20))
plot(1:20, 1:20, col=cols)
MrFlick
  • 195,160
  • 17
  • 277
  • 295
1

You can also use the colorRamp function from base R to map the values to RGB colors and then use the rgb function to convert to hexadecimal format.

An example :

# I use hex numbers between 0.3 and 0.7 (instead of O and 1) to show that the ggplot scale used the 
# minimum and maximum values by defaults (as done in the python examples you provided)
set.seed(123)
d <- data.frame(
    hex = sort(runif(20, 0.3, 0.7)),
    x = 1:20,
    y = 1
)

# Graph with ggplot and scale_fill_gradient2
ggplot(d, aes (x, y, fill = hex)) + geom_bar(stat = "identity") +
    scale_fill_gradient2 (low = "red", mid = "white", high = "blue", midpoint = 0.5)


# Normalize the vector to use the minimum and maximum values as extreme values
hexnorm <- (d$hex - min(d$hex)) / (max(d$hex) - min(d$hex))

# Map the hex values to rgb colors
mycols <- colorRamp(c("red", "white", "blue"), space = "Lab")(hexnorm)
# Transform the rgb colors in hexadecimal format
mycols <- rgb(mycols[,1], mycols[,2], mycols[,3], maxColorValue = 255)
mycols

# Check that you obtain the same result as the scale_fill_gradient2 ggplot function
ggplot(d, aes (x, y)) + geom_bar(stat = "identity", fill = mycols) 
Gilles San Martin
  • 4,224
  • 1
  • 18
  • 31