如何设置栅格:: plot的显示范围?

时间:2012-10-22 05:01:34

标签: r plot spatial raster

摘要

如何将R raster::plot的显示限制为Raster *对象的边界?为什么我问:

我是R初学者,必须

  1. 将未投影(lon-lat)全局空间数据从ASCII转换为netCDF(已解决)
  2. “regrid”it:即将数据限制在一个区域,投影它,并缩小尺寸(减小gridcells的大小)它(主要是解决了)
  3. 不幸的是,在科学工作中,一个主要是QAs数据转换,例如通过视觉检查。上面的步骤1看起来不错。但是,尽管第2步现在看起来好多了,但我真的想绘制重新划分extents的边界(或RasterLayer)。我在公共git存储库(here)中使用bash脚本驱动R代码执行转换步骤,并绘制转换后的输出apparently correctly。但是,我尝试使用raster::plot绘制regridding的输出并不完全正确(请参阅输出here的前3页)。

    如何解决?

    细节

    背景

    我需要获取一些数据(全球海洋排放清单(EI)),将其与其他数据(主要是其他EI)相结合,并将其输入模型。该模型想要消耗netCDF,并且它希望空间域上的netCDF略大于连续的美国(CONUS)。此图像AQMEII-NA domain的边框是域的边界。 (注意,域的一部分,但只有部分是海洋的。)该模型还希望netCDF以某种方式投射(LCC以12公里的分辨率)。我将此视为两个独立的问题:

    1. 将全局EI从其原生ASCII格式转换为netCDF
    2. 将来自全球/未投影的netCDF“重新划分”为缩小的(更精细的分辨率)投影子域。
    3. 我正在尝试使用this public git repository存档的代码解决这些问题。如果您克隆该git repo,然后按照“第一个示例”in the README所述配置/运行bash驱动程序GEIA_to_netCDF.sh(并假设您的R已正确配置,特别是packages = {{1} },raster)它将输出netCDF并绘制(使用ncdf4)输出到PDF的内容,如下所示:GEIA global marine emissions。输出数据的分布似乎是正确的,因此问题1似乎已经解决了。

      问题

      解决问题2(又名“第二个例子”in the README)似乎需要R package = fields::image.plot。我的bash驱动程序regrid_GEIA_netCDF.sh调用regrid.global.to.AQMEII.rin repository},它运行时没有错误,并显示其输出的PDF。 GEIA_N2O_oceanic_regrid.pdf包含4个页面,对应于raster末尾的4个代码块。这里只有前3页相关(第4页尝试使用regrid.global.to.AQMEII.r并且遇到更大问题)。

      Page = 1/4来自简化fields::image.plot重新排序的输出,加上来自raster::plot的CONUS地图的预计版本:

      wrld_simpl

      不幸的是,输出看起来是全局的,或几乎是全局的:raster::plot bounds problem但是输出被重新划分的所需域要小得多:AQMEII-NA domain。所以我有3个问题(1个主要问题,2个后续问题):

      1. plot(out.raster) plot(map.us.proj, add=TRUE) 默认显示的图片是否只显示 参数中给出的raster::plot范围
      2. 如果是这样,我的regrid有什么问题? (更多下面)
      3. 如果不是(即,如果RasterLayer默认显示 more 而不是其raster::plot的范围),如何使RasterLayer仅显示范围那raster::plot
      4. 执行重新编译的RasterLayerhere)中的代码似乎得到了正确的输出:

        regrid.global.to.AQMEII.r

        请注意,CRS似乎与给定here的输出域的定义相匹配。 (进入链接页面后,滚动浏览地图。)

        out.crs <- '+proj=lcc +lat_1=33 +lat_2=45 +lat_0=40 +lon_0=-97 +x_0=-2556000 +y_0=-1728000'
        

        但是,如上所述,regrid输出(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 )在其CRS中显示为lon-lat:我不确定为什么会这样,或者它是否暗示out.raster是全局的盘区。

        我还试图以两种方式限制情节本身:

        首先,我尝试在情节中添加out.raster,即

        extents

        生成the PDF的page = 2/4。不幸的是,这根本不会改变输出:AFAICS,它与page = 1/4完全相同(上图)。

        其次,我尝试使用plot(out.raster, ext=template.raster) plot(map.us.proj, add=TRUE) 来绑定重新划分的netCDF本身,然后使用我用来绑定regrid的相同raster::crop对象(RasterLayer)进行绘制:

        template.raster

        生成the PDF的page = 3/4。不幸的是,它显然与page = 1/4(上图)完全相同。

        (如果你想知道,PDF的第4页是使用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) 生成的,它有一个不同的问题,描述为here,除非StackOverflow破坏了该链接。)

        非常感谢您对这位R新手的帮助!

1 个答案:

答案 0 :(得分:3)

摘要

我的问题

How to limit display of an R `raster::plot` to the bounds of a `Raster*` object?

是基于我对问题的错误诊断。解决方案是正确设置底层extent 数据对象的边界(或Raster*)(即绘图数据的来源),特别是

  1. 通过查询其基础文件来获取模板对象的边界(用于创建数据对象)(不做任何假设!)
  2. 通过查询其基础文件来获取模板对象的CRS(不做任何假设!)
  3. 直接设置模板对象的边界和CRS
  4. 但是

    • 不要试图仅在Extent上设置分辨率;对我来说,至少,挂起
    • raster::plot地图仍有一个小的边界问题;至少,相对于我使用fields::image.plot
    • 的地图

    细节

    这个问题的答案实际上是另一个问题的答案:如何正确设置extent对象的Raster*?因为一旦我正确设置了我想要绘制的对象的范围,raster::plot问题就会消失。 (有一个小例外 - 见下文。)这可能是主要的raster开发人员Robert J. Hijmans试图在this post中传达的内容,但如果是这样的话,我并没有察觉到当时。

    我在得到两个建议之后解决了这个问题,这些建议本身并不是我所需要的,但它让我走上了正确的道路。在这种情况下,该路径导致R package M3,这对于处理CMAQ和WRF输入和输出的数据非常有用。建议是

    1. 使用project.lonlat.to.M3进行重新审核任务。
    2. 情节问题可能与球形投影的生成模型(CMAQ)的假设有关。
    3. 第二个建议似乎有道理,因为我知道我正在使用+ellps=WGS84来设置CRS。 (请参阅this repository中大量注释的R,特别是regrid.global.to.AQMEII.r。)所以我决定调查一下。

      我知道第一个建议只会有困难(因为它只能投射点数),但是看看M3 doc只是为了确定。 ToC中的以下功能立即引起了我的注意:

      1. get.proj.info.M3,它不仅从模板文件中返回一个球形PROJ.4字符串,而且还有一个没有我认为需要提供的错误东方和北方的字符串:

        # use package=M3 to get CRS from template file
        out.crs <- get.proj.info.M3(template.in.fp)
        cat(sprintf('out.crs=%s\n', out.crs)) # debugging
        # out.crs=+proj=lcc +lat_1=33 +lat_2=45 +lat_0=40 +lon_0=-97 +a=6370000 +b=6370000
        
      2. get.grid.info.M3,可以通过一些努力返回模板文件的边界/范围:

        extents.info <- get.grid.info.M3(template.in.fp)
        extents.xmin <- extents.info$x.orig
        extents.xmax <- max(
          get.coord.for.dimension(
            file=template.in.fp, dimension="col", position="upper", units="m")$coords)
        extents.ymin <- extents.info$y.orig
        extents.ymax <- max(
          get.coord.for.dimension(
            file=template.in.fp, dimension="row", position="upper", units="m")$coords)
        template.extents <-
          extent(extents.xmin, extents.xmax, extents.ymin, extents.ymax)
        
      3. 然后可以在模板Raster*

        上设置这些边界
        template.in.raster <- raster(template.in.fp, ...)
        template.raster <- projectExtent(template.in.raster, crs=out.crs)
        template.raster@extent <- template.extents
        

        并使用模板重新输入Raster*

        out.raster <-
          projectRaster(
            # give a template with extents--fast, but gotta calculate extents
            from=in.raster, to=template.raster, crs=out.crs,
            # give a resolution instead of a template? no, that hangs
        #    from=in.raster, res=grid.res, crs=out.crs,
            method='bilinear', overwrite=TRUE, 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)
        # above fails to set CRS, so
        out.raster@crs <- CRS(out.crs)
        

        (如上所述,通过设置模板进行重新设置仅花费7秒,但通过设置网格分辨率进行重新登录,在2小时后,当我杀死作业时无法完成。)之后,raster::plot

        map.us.unproj <- wrld_simpl[wrld_simpl$ISO3 %in% c('CAN', 'MEX', 'USA'),]
        map.us.proj <-
          spTransform(map.us.unproj, CRS(out.crs)) # projected
        ...
        pdf(file=pdf.fp, width=5.5, height=4.25)
        ...
        plot(out.raster, # remaining args from image.plot
          main=title, sub=subtitle,
          xlab='', ylab='', axes=F, col=colors(100),
          axis.args=list(at=quantiles, labels=quantiles.formatted))
        # add a projected CONUS map
        plot(map.us.proj, add=TRUE)
        

        几乎与预期一样,但有一个例外:excess north-south plot extents with raster::plot地图超出了数据的界限到北部和南部(虽然不是东部和西部),导致图像与发布的图像不完全相似域名,例如this。有趣的是,当我用fields::image.plot作为

        进行绘图时
        # see code in
        # https://github.com/TomRoche/GEIA_to_netCDF/blob/master/plotLayersForTimestep.r
        plot.raster(
          raster=out.raster,
          title=title,
          subtitle=subtitle,
          q.vec=probabilities.vec,
          colors,
          map.cmaq
        )
        

        我没有遇到这个问题:fields::image.plot after problem fixed。所以我可能会使用fields::image.plot进行展示,至少目前是这样。