Question

I’m converting colours to HSV in order to remap the colour. In fact, I am generating a gradient of grey colours with gray.colors:

(mydata <- 1 : 10) # For exposition only
cols <- gray.colors(max(mydata))

However, what I actually want is a gradient of white–red instead of white–black. A bit of fiddling with the colour picker has convinced me that for this it should be enough to swap the value and saturation on the greyscale colours and then set the value to 1 (the hue of 0 already corresponds to red).

Nothing’s easier:

hsvc <-rgb2hsv(col2rgb(cols))
hsvc['s', ] <- hsvc['v', ]
hsvc['v', ] <- 1

However, in order to plot these values I now need to convert them back to R colour values. I don’t seem to be able to do this because of a missing hsv2col. Sure, there’s hsv which purports to do this but you cannot call it with the value of hsvc above – not even with a single column:

hsv(hsvc[, 1]) # plots *three* (wrong) colour values instead of one

And R cannot use the HSV values directly:

plot(1, 1, pch = 20, col = cols[1])   # Works, grey dot
plot(1, 1, pch = 20, col = hsvc[, 1]) # Nothing plotted

How do I get R-usable colour values back from the matrix of HSV values?

Was it helpful?

Solution

Use do.call and as.list to pass the data to the relevant arguments of hsv:

do.call(hsv,as.list(hsvc[,1]))
[1] "#FFB3B3"

plot(1,1, pch=20, col=do.call(hsv,as.list(hsvc[,1]))) # light red dot

To do this for all you data:

plot(mydata,col=apply(hsvc,2,function(x) do.call(hsv,as.list(x)))) # a symphony of red

But it appears that the remapping has not worked correctly, since the intensity changes do not work in the same direction.

OTHER TIPS

You want:

> do.call(hsv, as.list(hsvc[, 1]))
[1] "#FFB2B2"

But then you really need to generalise that to work on all columns of hsvc, so how about:

sapply(data.frame(hsvc), function(x) do.call(hsv, as.list(x)))

which gives

> sapply(data.frame(hsvc), function(x) do.call(hsv, as.list(x))) 
       X1        X2        X3        X4        X5        X6        X7        X8 
"#FFB2B2" "#FF9393" "#FF7C7C" "#FF6969" "#FF5858" "#FF4A4A" "#FF3C3C" "#FF3030" 
       X9       X10 
"#FF2424" "#FF1919"

or more nicely

> apply(hsvc, 2, function(x) do.call(hsv, as.list(x)))
 [1] "#FFB2B2" "#FF9393" "#FF7C7C" "#FF6969" "#FF5858" "#FF4A4A" "#FF3C3C"
 [8] "#FF3030" "#FF2424" "#FF1919
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top