Search code examples
rgraphic

Rescaling colors palette in r


In R i have a cloud of data around zero ,and some data around 1, i want to "rescale" my heat colors to distinguish lower numbers.This has to be done in a rainbow way, i don't want "discrete colors".I tried with breaks in image.plot but it doesn't work.

  image.plot(X,Y,as.matrix(mymatrix),col=heat.colors(800),asp=1,scale="none")

I tried :

lowerbreak=seq(min(values),quantile2,len=80)
  highbreak=seq(quantile2+0.0000000001,max(values),len=20)
  break=c(lowerbreak,highbreak)
  ii <- cut(values, breaks = break, 
            include.lowest = TRUE)

  colors <- colorRampPalette(c("lightblue", "blue"))(99)[ii]

Solution

  • Here's an approach using the "squash" library. With makecmap(), you specify your colour values and breaks, and you can also specify that it should be log stretched using the base parameter. It's a bit complex, but gives you granular control. I use it to colorize skewed data, where I need more definition in the "low end".

    To achieve the rainbow palette, I used the built-in "jet" colour function, but you can use any colour set - I give an example for creating a greyscale ramp with "colorRampPalette".

    Whatever ramp you use, it will take some playing with the base value to optimize for your data.

    install.packages("squash")
    library("squash")
    
    #choose your colour thresholds - outliers will be RED
    minval=0   #lowest value to get a colour
    maxval=2.0 #highest value to get a colour
    n.cols=100 #how many colours do you want in your palette?
    col.int=1/n.cols
    
    #create your palette
    colramp=makecmap(x=seq(minval,maxval,col.int),
                     n=n.cols,
                     breaks=prettyLog,
                     symm=F,
                     base=10,#to give ramp a log(base) stretch
                     colFn=jet,
                     col.na="red",
                     right=F,
                     include.lowest=T)
    
    # If you don't like the colFn options in "makecmap", define your own!
    #   Here's an example in greyscale; pass this to "colFn" above
    user.colfn=colorRampPalette(c("black","white"))
    

    Example for using colramp in a plot (assuming you've already created colramp as above somewhere in your program):

    varx=1:100
    vary=1:100
    plot(x,y,col=colramp$colors) #colors is the 2nd vector in the colramp list
    

    To select specific colours, subset from the list via, e.g., colors[1:20] (if you try this with the example above, the first colors will repeat 5 times - not really useful but you get the logic and can play around).

    In my case, I had a grid of values that I wanted to turn into a coloured raster image (i.e. colour mapping some continuous data). Here's example code for that, using a made up matrix:

    #create a "dummy matrix"
    matx=matrix(data=c(rep(2,50),rep(0,500),rep(0.5,500),rep(1,500),rep(1.5,500)),nrow=50,ncol=41,byrow=F)
    
    #transpose the matrix
    #  the output of "savemat" is rotated 90 degrees to the left
    #  so savemat(maty) will be a colorized version of (matx)
    maty=t(matx)
    
    #savemat creates an image using colramp
    savemat(x=maty,
        filename="/Users/KeeganSmith/Desktop/matx.png",
        map=colramp,
        outlier="red",
        dev="png",
        do.dev.off=T)
    

    The resulting image of matx