7
votes

[Here top images is output from R 3.2.5, same code produces bottom image in R 2.15.2, notice the diff in color scale labels on the right side. I want to resolve the 'shift' of labels in the top plot. Sample code given in this query was used to generate both plots.

Notice the diff in color scale label on two images. top image is the output from R 3.2.5, same code produces bottom image in R 2.15.2. I want to resolve the 'shift' of labels in the top plot to match the bottom one. Sample code given in this query was used to generate both plots.

I am trying to plot a map using image.plot but the min and max value of colorscale are not displayed exactly at the tips. I am facing this issue in R version 3.2.5 (2016-04-14); Platform: x86_64-w64-mingw32/x64 (64-bit) and library package 'fields' Spam version 1.4-0 (2016-08-29)

In contrast, the same commands could be correctly displayed the min and max values at the edges of color scale in R version 2.15.2 (2012-10-26), Platform: x86_64-w64-mingw32/x64 (64-bit) and 'fields' package 0.41-0 (2014-02-26). Here is sample code:

library(fields)
temp <- matrix(data=rexp(200, rate=10), nrow=180, ncol=360)
min(temp)
max(temp)
color_plate <- c("#FF0000", "#FF4D00", "#FF7000", "#FF8A00", "#FFA800", "#FFBF00", "#FFF000", "#FFFF54", "#AAFFFF","#7FFFFF", "#55FFFF", "#2AFFFF", "#00CFFF", "#20BFFF", "#209FFF", "#2060FF")

zlim <- seq(0.08,0.40,by=0.04)
temp[temp<min(zlim)] <- min(zlim)
temp[temp>max(zlim)] <- max(zlim)

image.plot(temp,col=color_plate, 
           axis.args=list(cex.axis =1,at=zlim, labels=zlim,mgp=c(1, 0, 0),tck=0.1))
2
hi, Can anyone help me, I also tried R version 3.3.1 and getting similar issue..Munish
I don't have R-2.15.2 available to test, so I cannot compare results. I don't know what you mean by "exactly at the tips". Can you provide images from both versions with a clear description of the problem area?r2evans
Hi, I have added screenshots of output in two versions in the question.Munish
Perhaps it's a matter of opinion, but I interpret the top (more recent) image to be more representative: since the gradient is discretized, the 0.04 and 0.8 are perfectly aligned (centered vertically) with the swatch of their respective colors. Having said that, I'll see if I can find a way to adjust it ...r2evans
Please suggest anything you find usefulMunish

2 Answers

6
votes

The best I could do to answer this question was to escape the confines of image.plot()and recode the heat map in ggplot2. The code I wrote should relocate your tick marks to the appropriate locations. Note that "Var1" and "Var2" in the ggplot object p can be switched depending on how you want the data displayed. I used melt() to transform the temp object which means that the original row/column designation is lost. I wasn't sure which plotted on the x/y axis in the image.plot() function, so if I chose the wrong one be sure to switch "Var1" and "Var2".

I hope this helps!

library(fields)
library(reshape2)
library(ggplot2)
library(grid)

temp <- matrix(data=rexp(200, rate=10), nrow=180, ncol=360)

color_palette <- c("#FF0000", "#FF4D00", "#FF7000", "#FF8A00",
        "#FFA800", "#FFBF00", "#FFF000", "#FFFF54", "#AAFFFF","#7FFFFF",
        "#55FFFF", "#2AFFFF", "#00CFFF", "#20BFFF", "#209FFF", "#2060FF")

zlim <- seq(0.08,0.40,by=0.04)
zlim2 <- seq(0.08,0.40,by=0.02)

temp[temp<min(zlim)] <- min(zlim)
temp[temp>max(zlim)] <- max(zlim)
rownames(temp) <- seq(0,1,1/(length(temp[,1])-1))
colnames(temp) <- seq(0,1,1/(length(temp[1,])-1))

tdm <- melt(temp)

tdm$val_for_color <- NA
##can change this as long as you end up with 17 classes (labeled 1-17) for color assignment
for(i in 1:(length(zlim2)-1)){
    tdm$val_for_color[which(tdm$value >= zlim2[[i]] & tdm$value <= zlim2[[i+1]] )] <- i
}

p <- ggplot(tdm, aes(x = Var1, y = Var2, fill = val_for_color)) +
        geom_raster() + scale_fill_gradientn(breaks=seq(1,length(zlim),1),colors=color_palette, labels=zlim)+ 
        scale_x_continuous(expand=c(0,0)) +
        scale_y_continuous(expand=c(0,0)) +
        guides(fill = guide_colorbar(draw.ulim = TRUE,draw.llim = FALSE,
                        barwidth = 0.7, barheight = 10, limits=c(min(zlim),max(zlim)), raster=FALSE,
                        ticks=FALSE,
                        title=NULL))+
        ylab(NULL)+
        xlab(NULL)+
        theme_bw()

g <- ggplotGrob(p)

#this shifts and spreads the labels
d <-g$grobs[[15]][[1]][[1]]$grobs[[3]]$y[[1]]
g$grobs[[15]][[1]][[1]]$grobs[[3]]$y[[1]] <- g$grobs[[15]][[1]][[1]]$grobs[[3]]$y[[1]]-d
for(i in 2:length(g$grobs[[15]][[1]][[1]]$grobs[[3]]$y)){
    g$grobs[[15]][[1]][[1]]$grobs[[3]]$y[[i]] <- d*5*(i-1)
}

grid.draw(g)
5
votes

I got the answer from package creator of fields package. Pasting the sample code here for others..

library(fields)

temp <- matrix( seq( 0,.5,,80), 8,10)

colTab <- c("#FF0000", "#FF4D00","#FF7000", "#FF8A00", "#FF7000")

N<- length( colTab)

breaks <- seq(0.08, 0.40,  length.out= N+1 )

image.plot(temp, col=colTab, breaks=breaks,
           axis.args=list(cex.axis =1, at=breaks, labels= breaks, mgp=c(1, 0, 0), tck=0.1)
     )