Search code examples
rplotlegendrasterscientific-notation

Generate a common legend (scale) for 2 rasters underneath the plots using scientific notation


I am trying to plot 2 rasters with different values with the same scale for comparison. I have been trying to work out the answer using this and this.

I am running into two issues:

  1. I would like to be able to have the legend labels in scientific notation (there are too many decimal places to be of any use)
  2. I would like there to be one scale for both plots, at the bottom.

I am familiar with using legend(), but am not sure how to set the position/direction of the scale and the scientific notation using plot. I have generated some sample data to show the problem I am running into:

library(raster)
set.seed(10)
x = runif(2000000, -0.0005, .9875)
y = runif(2000000, -0.0008, .99)
xmat = matrix(x, nrow = 500)
ymat = matrix(x, nrow = 500)
xras = raster(xmat)
yras = raster(ymat)
min_ = min(minValue(xras), minValue(yras))
max_ = max(maxValue(xras), maxValue(yras)) 

To plot the data I am using:

par(mfrow = c(2,1))
plot( xras, col=rev( rainbow( 99, start=0,end=1 ) ), breaks=seq(min_,max_,length.out=100), legend = FALSE,  axes = FALSE )
plot( yras, col=rev( rainbow( 99, start=0,end=1 ) ), breaks=seq(min_,max_,length.out=100), legend = FALSE, axes = FALSE )
r.range = c(min_, max_)

And to generate the legend I am using:

plot(xras, legend.only=TRUE, col=rev( rainbow( 99, start=0,end=1 ) ),  legend.width=1, legend.shrink=0.75, axis.args=list(at=seq(r.range[1], r.range[2], abs(r.range[1]-r.range[2])/4), labels=seq(r.range[1], r.range[2], abs(r.range[1]-r.range[2])/4), cex.axis=0.6), legend.args=list(text='Precipitation (m)', side=1, font=2, line=2.5, cex=0.8))

I am open to any method/packages to solve this problem. I have seen that image() is a popular solution for plotting rasters, but would prefer to be able to keep the projection associated with the raster.

To reiterate what I am hoping for: two raster plots displayed (that have different, but similar values (see example)), with a common legend underneath, using scientific notation.


Solution

  • This is a try. It will need more refinement:

    library(rasterVis)
    set.seed(10)
    x = runif(2000000, -0.0005, .9875)
    y = runif(2000000, -0.0008, .99)
    xmat = matrix(x, nrow = 500)
    ymat = matrix(x, nrow = 500)
    xras = raster(xmat)
    yras = raster(ymat)
    min_ = min(minValue(xras), minValue(yras))
    max_ = max(maxValue(xras), maxValue(yras))
    r.range = c(min_, max_)
    
    levelplot(stack(xras, yras), col.regions = rev(rainbow(99, start=0, end=1)), colorkey = list(space = "bottom"))
    

    enter image description here