3

I am trying to improve the color shadings of a levelplot. Please take a look at the code below:

# Load required packages
library(raster)
library(rasterVis)
library(viridis)

# Download file
download.file('https://www.dropbox.com/s/caya1ja5ukpih9e/raster_thiago.tif?dl=1',
              destfile="~/Desktop/raster_thiago.tif", method="auto")

# Open file
r <- readAll(raster("~/Desktop/raster_thiago.tif"))

# Raster version
plot(r, col=viridis_pal(option="D")(255))

enter image description here

Please note how this map looks sharp when plotted with raster::plot. The color shadings are smooth, and you can't see any "contours" between them. However, sadly raster plots are not as customizable as levelplots.

Now, take a look at this attempt to do the same with RasterVis:

# RasterVis version
levelplot(r, margin=FALSE,
          par.settings=rasterTheme(viridis_pal(option = "D")(255)))

enter image description here

Do you see how this map is not as sharp as the previous one? It looks like the color palette doesn't have the same resolution, and you can see how the edges between the color gradients are not as smooth.

Is there any way to improve this look? I've tried to play around with the par.settings and col.regions arguments, but none of them seems to work. I am probably missing something...

thiagoveloso
  • 2,537
  • 3
  • 28
  • 57

2 Answers2

4

With levelplot(), you will also need to explicitly supply an at = argument, a numeric vector giving the breakpoints between the levels to which the colors in col.regions = correspond. Here is a simple reproducible example:

library(rasterVis)
library(viridis)

## Example raster
f <- system.file("external/test.grd", package="raster")
r <- raster(f)

## Option 1: Use `at=` and `col.regions=` to set color gradient
nlev <- 200
my.at <- seq(from = cellStats(r, "min"),
             to = cellStats(r, "max"),
             length.out = nlev + 1)
my.cols <- viridis_pal(option = "D")(nlev)
levelplot(r, margin = FALSE,
          at = my.at,
          col.regions = my.cols)


## Option 2: Pass options via `par.settings = rasterTheme()`
##
## (NOTE: this only works for nlev up to 100)
nlev <- 100
my.at <- seq(cellStats(r, "min"), cellStats(r, "max"),
             length.out = nlev + 1)
my.theme <- rasterTheme(viridis_pal(option = "D")(nlev))
levelplot(r, margin = FALSE,
          at = my.at,
          par.settings = my.theme)

To see that this works, compare plots drawn using nlev = 10 and nlev = 200:

enter image description here

Josh O'Brien
  • 159,210
  • 26
  • 366
  • 455
  • Thanks Josh. Option #2 was not very good looking on my data for some reason, but option #1 did the trick. – thiagoveloso Aug 09 '19 at 07:55
  • 1
    @thiagoveloso Happy to hear that worked for you! I'm still curious about why the `par.settings = rasterTheme()` option doesn't work with more than 100 colors. I believe it's related to the default maximum of 100 regions mentioned in the `col.regions` description in `?lattice::levelplot`, but that's as far as I got when trying to track down the problem. – Josh O'Brien Aug 09 '19 at 14:45
2

I'd like to suggest an option 3 using maxpixels

require(raster)
require(rasterVis)

pal=colorRampPalette(c("#4575B4","#74ADD1","#E0F3F8","white","#FEE090","#F46D43","#D73027"))
proj <- CRS('+proj=longlat +datum=WGS84')

df <- expand.grid(x = seq(-2, 2, .01), y = seq(-2, 2, .01))
df$z <- with(df, (3*x^2 + y)*exp(-x^2-y^2))
r <- rasterFromXYZ(df, crs=proj)

my.brks=seq(-0.6,1.2,by=0.2)
my.labels=as.character(round(my.brks,digits=1))

Default plot

levelplot(r, col.regions=pal, margin=FALSE,at=my.brks,scales=list(draw=FALSE),xlab=NULL,ylab=NULL)

enter image description here

If maxpixels is set, the result looks smoother just like raster::plot()

levelplot(r, col.regions=pal, margin=FALSE,at=my.brks,scales=list(draw=FALSE),xlab=NULL,ylab=NULL, maxpixels = 1e6)

enter image description here

Fallen lord
  • 196
  • 1
  • 12