summary
How to limit display of an R raster::plot
to the bounds of a Raster* object? Why I ask:
I'm an R beginner who must
- convert unprojected (lon-lat) global spatial data from ASCII to netCDF (solved)
- "regrid" it: i.e., restricted the data to a region, project it, and downscale (decrease the size of the gridcells) it (mostly solved)
Unfortunately, in scientific work, one mostly QAs data transformations such as this by visual inspection. Step 1 above looks good. But though step 2 now looks much better, I really want to plot only the bounds (or extents
) of the regridded RasterLayer
. I have R code driven by bash scripts in a public git repository (here) that does the conversion step, and plots the converted output, apparently correctly. However my attempts to plot the output of the regridding with raster::plot
are not quite right (see first 3 pages of output here).
How to fix?
details
background
I need to take some data (a global marine emissions inventory (EI)), combine it with other data (mostly other EIs), and input that to a model. The model wants to consume netCDF, and it wants that netCDF over a spatial domain slightly bigger than the contiguous US (CONUS). The borders of this image are the boundaries of the domain. (Note that part, but only part, of the domain is oceanic.) The model also wants that netCDF projected a certain way (LCC at 12-km resolution). I'm treating this as 2 independent problems:
- convert the global EI from its native ASCII format to netCDF
- "regrid" the netCDF from global/unprojected to the downscaled (finer-resolution), projected subdomain.
I'm attempting to solve these problems with code I have archived at this public git repository. If you clone that git repo, and then configure/run the bash driver GEIA_to_netCDF.sh
as described for the "first example" in the README (and presuming your R is appropriately configured, notably with packages=raster
, ncdf4
) it will output netCDF and plot (using fields::image.plot
) that output to a PDF, which should look like this: . The distribution of the output data appears correct, so problem 1 seems solved.
problem
Solving problem 2 (aka the "second example" in the README) seems to require R package=raster
. My bash driver regrid_GEIA_netCDF.sh
calls regrid.global.to.AQMEII.r
(both in repository), which runs without error, and displays a PDF of its output. GEIA_N2O_oceanic_regrid.pdf
comprises 4 pages, corresponding to 4 blocks of code at the end of regrid.global.to.AQMEII.r
. Only the first 3 pages are relevant here (the 4th page tries to use fields::image.plot
and has bigger problems).
Page=1/4 results from a simple raster::plot
of the regridded output, plus a projected version of a CONUS map from wrld_simpl
:
plot(out.raster)
plot(map.us.proj, add=TRUE)
Unfortunately the output appears global, or nearly so: But the desired domain, to which the output was regridded, is much smaller: . So I have 3 questions (1 main question, 2 followups):
- Does the image displayed by
raster::plot
by default display only the extents of theRasterLayer
given in its arguments? - If so, what is wrong with my regrid? (more below)
- If not (i.e., if
raster::plot
by default displays more than the extents of itsRasterLayer
), how to makeraster::plot
display only the extents of thatRasterLayer
?
The code in regrid.global.to.AQMEII.r
(here) that does the regridding seems to get the correct output:
out.crs <- '+proj=lcc +lat_1=33 +lat_2=45 +lat_0=40 +lon_0=-97 +x_0=-2556000 +y_0=-1728000'
Note that CRS appears to match the definition of the output domain given here. (Once at the linked page, scroll past the map.)
out.raster <-
projectRaster(
from=in.raster, to=template.raster, method='bilinear', crs=out.crs,
overwrite=TRUE, progress='window', format='CDF',
# args from writeRaster
NAflag=-999.0, # match emi_n2o:missing_value,_FillValue (TODO: copy)
varname=data.var.name,
varunit='ton N2O-N/yr',
longname='N2O emissions',
xname='COL',
yname='ROW',
filename=out.fp)
out.raster
# made with CRS
#> class : RasterLayer
#> dimensions : 299, 459, 137241 (nrow, ncol, ncell)
#> resolution : 53369.55, 56883.69 (x, y)
#> extent : -14802449, 9694173, -6258782, 10749443 (xmin, xmax, ymin, ymax)
# ??? why still proj=longlat ???
#> coord. ref. : +proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0
#> data source : /home/rtd/code/R/GEIA_to_netCDF/GEIA_N2O_oceanic_regrid.nc
#> names : N2O.emissions
#> zvar : emi_n2o
But, as noted, the regrid output (out.raster
) shows itself to be lon-lat in its CRS: I'm not sure why that is, or if it implies out.raster
is global in extents.
I also tried to restrict the plot itself in two ways:
Firstly, I tried adding an extents
to the plot, i.e.,
plot(out.raster, ext=template.raster)
plot(map.us.proj, add=TRUE)
which generates page=2/4 of the PDF. Unfortunately, that does not change the output at all: AFAICS, it is completely identical to page=1/4 (above).
Secondly, I tried using raster::crop
to bound the regridded netCDF itself, before plotting that, using the same RasterLayer
object (template.raster
) that I used to bound the regrid:
template.raster.extent <- extent(template.raster)
out.raster.crop <-
# overwrite the uncropped file
crop(out.raster, template.raster.extent, filename=out.fp, overwrite=TRUE)
...
plot(out.raster.crop)
plot(map.us.proj, add=TRUE)
which generates page=3/4 of the PDF. Unfortunately, that it is also apparently completely identical to page=1/4 (above).
(In case you're wondering, page 4 of the PDF was generated using fields::image.plot
, which has a different problem, described here, unless StackOverflow whacks that link.)
Your assistance to this R newbie is appreciated!