简体   繁体   中英

Plotting filled contour map with discrete color scale

Thanks to this answer I've been able to plot maps from NetCDF files with the correct projection and overlay map. However, when plotting filled contour maps using ggplot, I encounter an error. (see the linked answer for the input file)

#See https://gis.stackexchange.com/questions/120900/plotting-netcdf-file-using-lat-and-lon-contained-in-variables

# First, estimate the extent.
# We start with the lat and long, then project it to the Lambert Conformal projection
library(raster)
inputfile <- "file.nc"

# Grab the lat and lon from the data
lat <- raster(inputfile, varname="xlat")
lon <- raster(inputfile, varname="xlon")

# Convert to points and match the lat and lons
plat <- rasterToPoints(lat)
plon <- rasterToPoints(lon)
lonlat <- cbind(plon[,3], plat[,3])

# Specify the lonlat as spatial points with projection as long/lat
lonlat <- SpatialPoints(lonlat, proj4string = CRS("+proj=longlat +datum=WGS84"))

# Need the rgdal package to project it to the original coordinate system
library("rgdal")

# My best guess at the proj4 string from the information given
mycrs <- CRS("+proj=lcc +lat_1=35.00 +lat_2=51.00 +lat_0=39.00 +lon_0=14.00 +x_0=-6000. +y_0=-6000. +ellps=sphere +a=6371229. +b=6371229. +units=m +no_defs")
plonlat <- spTransform(lonlat, CRSobj = mycrs)
# Take a look
plonlat
extent(plonlat)

# Yay! Now we can properly set the coordinate information for the raster
pr <- raster(inputfile, varname="pr")
# Fix the projection and extent
projection(pr) <- mycrs
extent(pr) <- extent(plonlat)
# Take a look
pr
plot(pr)

# Project to long lat grid
r <- projectRaster(pr, crs=CRS("+proj=longlat +datum=WGS84"))

library(rasterVis)
#Plot with ggplot:
#Add an overlay map
library(maps)
world    <-data.frame(map(plot=FALSE)[c("x","y")])
gplot(r*86400) + 
  geom_tile(aes(fill=value)) + 
  scale_fill_discrete() + 
  geom_path(aes(x,y), data=world) + 
  coord_equal(xlim=c(xmin(r), xmax(r)), ylim=c(ymin(r), ymax(r)))

Error: Continuous value supplied to discrete scale
This is because I want to plot a discrete contour map, with discrete colours, not with a continuous colour scale. Of course it works if using scale_fill_continuous.
I cannot use fill=factor(value) beacuse it will take ages (and GBs of memory) and then return me with a color entry for each single different value in the dataset. I could manually create some "bins" and modify the dataset to fit into those, but I feel this would be a workaround for a much easier solution.

What is the simple elegant solution I'm missing? Shouldn't I use geom_tile (or geom_raster)?

EDIT: Thsi is a pdf example of what I'd like to get: https://copy.com/yMDzEt4i1ELMxpca That plot is created with GrADS. The presence or absence of a color legend is not important, sometimes I use it sometimes I don't.

EDIT2: cut(value) could do but as stated I'd like a ggplot solution and additionally...

...is an example of what it produces. I'd like the labels to be between the colors, not above, like this:

Based on your edits I would do the following:

r$value.bin <- cut(r$value, c(0:4, 2 * (3:5)))
gplot(r*86400) + 
    geom_tile(aes(fill = value.bin)) + 
    scale_fill_manual(
       values = colorRampPalette(brewer.pal(9, "Greens"))(nlevels(r$value.bin))) + 
    geom_path(aes(x,y), data=world) + 
    coord_equal(xlim=c(xmin(r), xmax(r)), ylim=c(ymin(r), ymax(r)))

Maybe you have to play with the colours in scale_fill_manual and the cutting a bit such that there are spots with an NA color.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM