Question

I am trying to automatically grab data on wave height forecast and build plots similar this one.

Using R, I could download the data and plot it using:

library(rgdal)
library(fields)

ftp.string <- "ftp://polar.ncep.noaa.gov/pub/waves//20130205.t00z/nww3.HTSGW.grb"
#this link may become broken with time, as folders are removed after some time. just edit the date to reflect the most recent day at the time you run these lines

download.file(ftp.string, "foo.grb", mode="wb")

grib <- readGDAL("foo.grb")
is.na(grib$band1) <- grib$band1 > 100
image(grib, col=(tim.colors(15)), attr=1)

However, if you take a closer look at the link I posted above, you'll notice a subtile difference: the plot from the link spans more than 360 degrees in longitude.

This is important for what I'm doing as it allows me to easily check for swells on all oceans within the same plot - this is much harder if only 360 degrees are shown at a time, as that forcibly results in one of the oceans being cut.

Despite all my best efforts, I can't find a way to plot more than 360 degrees, as the GRIB format is 'too smart' to allow that (this is not just offsetting the data, but instead repeating a part of it).

Any insights will be greatly appreciated. Cheers

Was it helpful?

Solution 2

A more naive approach would be to create a second dataset, with an offset of 360°:

grib2 <- grib
grib2@bbox[1, ] <- grib2@bbox[1, ] - 360
image(grib, col=(tim.colors(15)), attr=1, xlim=c(-360,360))
image(grib2, add=TRUE, col=(tim.colors(15)), attr=1)

enter image description here

And you can play with xlim to center it the way you want:

image(grib, col=(tim.colors(15)), attr=1, xlim=c(-270,90))
image(grib2, add=TRUE, col=(tim.colors(15)), attr=1)

enter image description here

Here it works because the data is on a regular grid so there is no need for interpolation, otherwise of course, @Spacedman solution is to be preferred.

OTHER TIPS

I would load your data into a raster stack from the raster package and then use the merge and crop functions. Basically you duplicate the raster, shift it 360 degrees, then merge that with itself, then crop it to taste. Here's a function:

require(raster)
wwrap <- function(g,xmax=720){
  gE = extent(g)

  shiftE = extent(360,720,gE@ymin, gE@ymax)
  g2 = g
  extent(g2)=shiftE

  gMerge = merge(g,g2)

  crop(gMerge,extent(0,xmax,gE@ymin, gE@ymax))
}

And here's some usage:

> gstack = stack("foo.grb")
> gstack[gstack>100] = NA
> gstack2 = wwrap(gstack,xmax=460)
> plot(gstack2)
> plot(gstack2[[1]])
> plot(gstack2[[61]])

Probably more efficient to shift and crop the raster first, then merge, but this is a start and it only takes a few seconds to run on your raster.

If all you care about is plotting then it might be easier to write a function that plots it twice, once with a shift in extent. But that would have to be done for each band in your raster....

wraplot <- function(g,xmax=720){
  gE = extent(g)
  ## to setup the plot
  worldWrap = extent(0,xmax,gE@ymin, gE@ymax)
  rWrap = raster(nrows=1,ncols=1,ext=worldWrap)
  rWrap[]=NA
  plot(rWrap)
  ## first part
  plot(g,add=TRUE)
  ## setup and plot it again
  shiftE = extent(360,720,gE@ymin, gE@ymax)
  cropE = extent(360,xmax,gE@ymin, gE@ymax)
  extent(g)=shiftE
  g=crop(g,cropE)
  plot(g,add=TRUE)
}

Then you do:

wraplot(gstack[[1]])

Check out all the features of the raster package.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top