13

A quick question,

I have a vector with numbers, e.g:

values <- c(0.104654225, 0.001781299, 0.343747296, 0.139326617, 0.375521201, 0.101218053)

and I want to assign a gradient scale to this vector, I know that I can do it with

gray(values/(max(values))

but I would like to use a blue colour scale, for example using colorRampPalette or something similar,

Thanks

I've noticed that there are several questions with similar topics but they map intervals and I would like to map colours to numeric values

user2380782
  • 1,542
  • 4
  • 22
  • 60
  • If this is an R-specific question you should put that in the title, or at least the body of the question. – Tyler Durden Mar 07 '14 at 16:32
  • 1
    @TylerDurden no, he shouldn't http://meta.stackexchange.com/questions/19190/should-questions-include-tags-in-their-titles – Julián Urbano Mar 07 '14 at 16:44
  • The meta post just says there is no *requirement* to put the language in the title. Nevertheless, it is perfectly fine to do so, and in cases where the language is not one of the main languages, as it is here, I would suggest putting the language in the title to make it easy for people to ignore the question without perusing the tags. – Tyler Durden Mar 07 '14 at 16:48

2 Answers2

18

Edit: I now think using colorRampPalette() makes this a bit easier than does colorRamp().

## Use n equally spaced breaks to assign each value to n-1 equal sized bins 
ii <- cut(values, breaks = seq(min(values), max(values), len = 100), 
          include.lowest = TRUE)
## Use bin indices, ii, to select color from vector of n-1 equally spaced colors
colors <- colorRampPalette(c("lightblue", "blue"))(99)[ii]

## This call then also produces the plot below
image(seq_along(values), 1, as.matrix(seq_along(values)), col = colors,
      axes = F)

Among base R functions, colorRamp() is what you are looking for. As dg99 notes, it returns a function that maps values in the range [0,1] to a range of colors.

Unfortunately, it returns a matrix of RGB values, which is not directly usable by most of R's plotting functions. Most of those functions take a col= argument which "wants" sRGB values expressed as hex values in strings that look like "#E4E4FF" or "#9F9FFF". To get those you'll need to apply the rgb() function to the matrix returned by colorRamp(). Here's an example:

f <- colorRamp(c("white", "blue"))
(colors <- rgb(f(values)/255))
# [1] "#E4E4FF" "#FFFFFF" "#A7A7FF" "#DBDBFF" "#9F9FFF" "#E5E5FF"

In practice, you'll probably want to play around with both the color scale and the scaling of your values.

## Scale your values to range between 0 and 1
rr <- range(values)
svals <- (values-rr[1])/diff(rr)
# [1] 0.2752527 0.0000000 0.9149839 0.3680242 1.0000000 0.2660587

## Play around with ends of the color range
f <- colorRamp(c("lightblue", "blue"))
colors <- rgb(f(svals)/255)

## Check that it works
image(seq_along(svals), 1, as.matrix(seq_along(svals)), col=colors,
      axes=FALSE, xlab="", ylab="")

enter image description here

Josh O'Brien
  • 159,210
  • 26
  • 366
  • 455
1

I think you're looking for colorRamp instead of colorRampPalette, as it will return a functor that will operate on floats from 0-1. Based on the first few lines of the example section in the documentation, maybe try something like:

f <- colorRamp(c("white", "blue"))
colors <- f(values)

or just

colors <- colorRamp(c("white", "blue"))(values)
dg99
  • 5,456
  • 3
  • 37
  • 49
  • `plot(values, pch=19, col=f(values))` plots in blue, yellow, pink and green – Julián Urbano Mar 07 '14 at 17:00
  • Yeah, definitely play around with the colors until you get what you want. Depending on your operating system, `R` may or may not support some of these color names. You might have to provide hex values. – dg99 Mar 07 '14 at 17:08