Simple way to contour netcdf variables on a map using r package - r

I have to draw maps using R package so that country limits are plotted, and also the contours for the values of a meteorological variable read from a NetCDF file.
I do the following:
r=raster('netcdffile.nc')
map('worldHires', xlim=c(-10,50), ylim =c(30,50))
plot(r, add = TRUE)
contour(r, add = TRUE)
but the country limits don't appear.
It seems that the plotting of the raster, eliminates the country limits previously drawn.
I need a simple wway, please.

Attaching an example netcdf file with correct coordinates would help. I don't have any netCDF file here on hand to test. Did you try the excellent rasterVis package? You can easily plot using trellis or ggplot, and add the map in the usual ways.
For example with rasterVis and ggplot2 something like this should work:
r=raster('netcdffile.nc')
library(rasterVis)
library(maps)
world <- data.frame(map(plot=FALSE)[c("x","y")])
gplot(r) +
geom_tile(aes(fill=value)) +
geom_path(data=world, aes(x,y)) +
stat_contour(aes(z=value)) +
coord_equal()

Related

Plotting nb object in ggplot?

I would like to plot the outline of UK, along with an nb object that I generated from a spatial points dataframe.
The problem is that the outline of UK takes really, really long to plot --it keeps crashing my Rstudio. This for example, either take really long to load or my Rstudio just stops responding.
library(raster)
UK_gadm <- getData("GADM", country="GB", level=0)
plot(UK_gadm)
So I resorted to using ggplot2 from this solution where I can get the outline of UK like in a fraction of a second with the following commands:
library(ggplot2)
UK <- map_data(map = "world", region = "UK") # changed map to "world"
ggplot(data = UK, aes(x = long, y = lat, group = group)) +
geom_polygon() +
coord_map()
The issue now is that I would like the nb object to be plotting against the backdrop of the outline of UK -- however, this seems only achievable in base R like for example:
plot(orotl.shp, xlim=c(-125, -115), ylim=c(42,47))
plot(orstationc.neighbors.dist, orstationc.loc, add=T, lwd=2, col="blue")
Is there any way I could plot nb objects in ggplot or is there a way for R to plot the outline of UK without crashing my computer with the base R plot function?
Managed to find a fast, simple solution after a whole night of effort. Hope this helps someone else with a similar issue.
Just to elaborate on the goal: plot a neighbours object (nb) against a shapefile. This is to visualise the linkages among certain coordinates. After some googling, I think this can only be done with base R's plot function. The problem however, was loading a country's shapefile (downloaded from official sources/gadm)-- its too big.
To solve this issue, get a more generalised, simple map of the country via the maps package, turn it into a shapefile and then plot it alongside the neighbours object.
Here's the code:
library(spdep)
# get your neighbour object from your spatial points df
rest_neighbours <- dnearneigh(rest_spdf,0,1)
library(maps)
# get boundary of UK
UK_map <- sf::st_as_sf(maps::map(database='world',regions='UK', plot = FALSE, fill = TRUE))
# write to shapefile
st_write(UK_map, 'shapefiles/UK.shp')
# henceforth, we can just call the shapefile
UK <- readOGR('shapefiles/UK.shp')
# plot the boundary and the neighbours
plot(UK)
plot(rest_neighbours, rest_coords, add=T, lwd=2, col="blue")
I did not realise that official boundary files are often really detailed which also means that they are really huge and I'm glad that there's ready-made watered down versions of the maps available in the maps package of r. (Sorry if you already knew -- I'm still learning!)
Hope this helps anyone else!

Plotting map facets using R

I am trying to plot lat/long using PlotOnStaticMap function from the RgoogleMaps library in R.
library(RgoogleMaps);library(plotrix);
mydata <- read.csv(file=name,header=T,sep=",")
map1 <- PlotOnStaticMap(lat = mydata1$latitude, lon = mydata1$longitude, zoom=1, cex=1, pch=1, col="green", FUN=points, add=F, size = c(640,640))
and then I am trying to create a facet using other field that has two values "Yes/No"
map1 + facet_grid(section_status ~.)
I understand the function "facet_grid" is from plotrix library.
However, is there any way to combine the two, or create a facet of Maps?

Plot a raster using hexes in ggplot2

I have a GIS raster data frame that I would like to plot using hexagonal tiles. The standard method using tile_geom() is straightforward:
ggplot(raster_df, aes(x, y, fill=blabla)) + geom_tile()
Howewer, I would really like my raster points to be displayed as hexes instead of rects for aesthetic reasons. The end result should be something like in this blog post: http://www.statsblogs.com/2014/09/02/how-to-create-a-hexagonal-bin-plot-in-sas/
I tried using geom_hex() instead of geom_tile(), but because geom_hex() seems to be intended with binning in mind, I can't figure out how to hack it to display my data instead. I would like for every raster point to correspond to a hex, i.e. have no binning at all!
Thank you for any suggestions.
Edit: as requested, here is a sample data raster (its actually very close to what I am using, as I want to plot a world map and colour each raster point according to a custom statistic)
library(maptools)
library(raster)
library(ggplot2)
data('wrld_simpl')
raster_df <- as.data.frame(rasterToPoints(rasterize(wrld_simpl, raster(res=5))))
raster_df$blabla <- rnorm(nrow(raster_df))
It looks as though this might be due to the implementation of geom_hex in ggplot2. I've used this package for a few years, and my first guess is to try:
ggplot(raster_df, aes(x, y, fill=blabla)) + geom_hex(stat="identity")
But this throws an error:
Error in ggplot2:::hexGrob(x = raster_df$x, y = raster_df$y, fill = raster_df$blabla) :
could not find function "hexcoords"
So I looked for the function hexcoords, which appears in the hexbin package. I explicity load that package and try again:
library(hexbin)
ggplot(raster_df, aes(x, y, fill=blabla)) + geom_hex(stat="identity")
And that works. The result isn't particularly beautiful, so it might be better to use the hexbin package a little more directly.
It doesn't seem that geom_hex() was designed to directly plot the data to hexagons without the interim step of stat = "binhex", which is different from many of the other geom_ functions.

How to make a ggplot2 contour plot analogue to lattice:filled.contour()?

I've been learning ggplot2, and hope to use it for all my R graphing. However, I've yet to find a way to make a contour plot that looks analogous to a conventional contour plot, like what can be obtained using lattice:filled.contour(). For example:
#define data
x<-seq(1,11,1)
y<-seq(1,11,1)
xyz.func<-function(x,y) {-10.4+6.53*x+6.53*y-0.167*x^2-0.167*y^2+0.0500*x*y}
#contour plot using lattice graphics and R Color Brewer
library(lattice) #for filled.contour()
library(RColorBrewer) #for brewer.pal()
z.lattice<-outer(x,y,xyz.func)
filled.contour(x,y,z.lattice,nlevels=6,col=brewer.pal(6,"YlOrRd"))
This gives me a nice contour plot.
Now, let's try the same thing in ggplot2. The best I can come up with, based on everything I've read (particularly Drawing labels on flat section of contour lines in ggplot2) is:
#contour plot using ggplot2
library(ggplot2)
library(reshape2) #for melt()
z.molten<-melt(z.lattice)
names(z.molten) <- c("x", "y", "z")
v<-ggplot(z.molten, aes(x,y,z=z))+
geom_tile(aes(fill=z))+
stat_contour(bins=6,aes(x,y,z=z), color="black", size=0.6)+
scale_fill_gradientn(colours=brewer.pal(6,"YlOrRd"))
v
This graph has the same basic idea as filled.contour(), but the colored tiles don't conform to the contours very well.
I haven't been successful with changing the sizes of the tiles, either.
Any suggestions on how to make ggplot2's output closer to filled.contour()'s output?
The essence of your question, it seems, is how to produce a contour plot in ggplot with discrete filled contours, rather than continuous contours as you would get using the conventional geom_tile(...) approach. Here is one way.
x<-seq(1,11,.03) # note finer grid
y<-seq(1,11,.03)
xyz.func<-function(x,y) {-10.4+6.53*x+6.53*y-0.167*x^2-0.167*y^2+0.0500*x*y}
gg <- expand.grid(x=x,y=y)
gg$z <- with(gg,xyz.func(x,y)) # need long format for ggplot
library(ggplot2)
library(RColorBrewer) #for brewer.pal()
brks <- cut(gg$z,breaks=seq(0,100,len=6))
brks <- gsub(","," - ",brks,fixed=TRUE)
gg$brks <- gsub("\\(|\\]","",brks) # reformat guide labels
ggplot(gg,aes(x,y)) +
geom_tile(aes(fill=brks))+
scale_fill_manual("Z",values=brewer.pal(6,"YlOrRd"))+
scale_x_continuous(expand=c(0,0))+
scale_y_continuous(expand=c(0,0))+
coord_fixed()
The use of, e.g., scale_x_continuos(...) is just to get rid of the extra space ggplot puts around the axis limits; fine for most things but distracting in contour plots. The use of coord_fixed(...) is just to set the aspect ratio to 1:1. These are optional.

R Plot Filled Longitude-Latitude Grid Cells on Map

I have a data frame containing a number of (x,y,z) data points, (x,y) is the lower-right coordinate of a longitude-latitude cell of size w (e.g. a 1-degree grid). The z value has been averaged over this cell.
I'd like to plot these points in R so that the entire grid cell is filled with some colour derived from z.
The result would look something like one of these images:
The projection itself (e.g. Lambert conformal conic, equirectangular) isn't important, just the grid cell plotting.
My data is sparse: not every longitude-latitude cell will have data associated with it.
My hope would be a solution similar to
library(maps)
map("state")
grid_points(my_data,c("x","y","z"),0.5)
where 0.5 is the grid resolution above, indicating a 0.5-degree cell.
Any thoughts?
Thanks!
An alternative to using either spplot or image is to use ggplot2. The relevant geometries are geom_raster and geom_tile. The first is supposed to perform better and yield smaller files, and the second is more standard. The following example call:
ggplot(aes(x = x, y = y, fill = value), data = dat_grid) + geom_tile() +
geom_path(data = ant_ggplot)
orginates from this blogpost of mine. In addition, ggplot2 supports a range of projections through the mapproj package, see coord_map for more details.
The following is a working example (provided you've defined YOUR_DATA to have x,y,z columns):
library(ggplot2)
library(maps)
us_states <- map_data("state")
(ggplot(aes(x=x,y=y,fill=z),data=YOUR_DATA) + geom_tile())+geom_polygon(data=us_states,aes(x=long, y=lat, group=group), colour="black", fill="white", alpha=0)
If your data.frame is "x", try this:
library(sp)
coordinates(x) <- c("x", "y", "z")
gridded(x) <- TRUE
image(x, col = terrain.colors(256), useRaster = TRUE)
To get a really exact answer you should provide a sample of your data, hopefully an entire data.frame or the source where you download and the code you used to read it into R.
If the code above fails at the gridded()<- step then it's likely your x and y values don't actually provide a regular grid, which is implied by your plots. If they really are gridded longitude/latitude values and you need to project them to the ones in your image then see the raster package, or more generally the rgdal package.
library(raster)
?projectRaster
library(rgdal)
?project
?spTransform
(The plots look to me like one of the "Albers Equal Area and Lambert Conformal Conic Projections of North America" as shown on this site: http://www.colorado.edu/geography/gcraft/notes/mapproj/mapproj_f.html).
See http://spatialreference.org to get the PROJ.4 string for your projection which you can use in sp or raster.
I tried to do that kind of map recently and ended up using function interp of library akima to intrapolate my z data into a regular grid before plotting (any kind of projections will have to be done prior to the use of interp):
library(akima)
interp(x,y,z,xo=seq(min(x),max(x),by=0.5),yo=seq(min(y),max(y),by=0.5),extrap=FALSE,linear=TRUE) -> xygrid
image(xygrid,breaks=seq(min(z),max(z),length=10), col=1:10)
You can do this:
library(raster)
r <- rasterFromXYZ(xyz)
plot(r)

Resources