Intersect the contour and polygon in R - r

I have been trying for a few days to create the contour and then plot the shapefile and contour on the same file. Now, that I am able to create the contour and shapefile on the same plot. I want to clip the contour with the shapefile an only show the shapefile.
The data temp.csv can be found on this link https://www.dropbox.com/s/mg2bo4rcr6n3dks/temp.csv
Shapefile can be found on the following location: https://www.dropbox.com/sh/ztvmibsslr9ocmc/YOtiwB8p9p
The script file image.scale.R can be found on the following location "https://www.dropbox.com/s/2f5s7cc02fpozk7/image.scale.R "
The code that I have used so far is as follows:
## Required packages
library(maptools)
library(rgdal)
library(sp)
library(maptools)
library(sm)
require(akima)
require(spplot)
library(raster)
library(rgeos)
## Set Working Directory
setwd("C:\\Users\\jdbaba\\Documents\\R working folder\\shape")
## Read Data from a file
age2100 <- read.table("temp.csv",header=TRUE,sep=",")
x <- age2100$x
y <- age2100$y
z <- age2100$z
####################################
##Load the shape file
#####################################
shapefile <- readShapePoly("Export_Output_4.shp")
fld <- interp(x,y,z)
par(mar=c(5,5,1,1)) filled.contour(fld)
###Import the image.scale
source source("image.scale.R")
# http://menugget.blogspot.de/2011/08/adding-scale-to-image-plot.html
x11(width=8, height=7)
layout(matrix(c(1,2), nrow=1, ncol=2), widths=c(6,1), height=6, respect=TRUE)
layout.show(2)
par(mar=c(4,4,1,2))
image(fld,axes=T)
contour(fld, add=TRUE)
#points(age2100$x,age2100$y, pch=".", cex=2,legend=F)
plot(shapefile,add=T,lwd=2)
box()
par(mar=c(4,0,1,4))
image.scale(fld, xlab="Eastings", ylab="Northings", xaxt="n", yaxt="n", horiz=FALSE)
axis(4)
mtext("Salinity", side=4, line=2.5)
The output of the above code is as follows:
Now, I want to get rid of the colored gradients and the contours from the polygon shapefile and only leave the intersection part.
Any help is highly appreciated.
Research: I found this link https://gis.stackexchange.com/questions/25112/clip-depth-contour-with-spatial-polygon on Stack exchange Gis and I tried to follow this method I always get error while creating the contour.
I found another similar thread on https://stat.ethz.ch/pipermail/r-sig-geo/2009-May/005793.html . But I couldn't make it work on my dataset.
I would like to acknowledge Marc in the box for helping me in getting to this point.
Thanks.

Indeed, #baptiste gave you a strong hint for the solution, the recent paper by Paul Murrell. Paul was generous to provide us with the code for his entire paper manuscript, which you can get from his personal website. On the side topic, Paul shows beautiful example of reproducible research with this paper. Generally, I took the following approach:
extract latitude and longitude coordinates from the shapefile (a function to do this is here, by Paul Hiemstra),
plot everything with your code,
and use polypath to remove everything outside the boundaries defined by shapefile, using extracted coordinates as a baseline.
#function to extract coordinates from shapefile (by Paul Hiemstra)
allcoordinates_lapply = function(x) {
polys = x#polygons
return(do.call("rbind", lapply(polys, function(pp) {
do.call("rbind", lapply(pp#Polygons, coordinates))
})))
}
q = allcoordinates_lapply(shapefile)
#extract subset of coordinates, otherwise strange line connections occur...
lat = q[110:600,1]
long = q[110:600,2]
#define ranges for polypath
xrange <- range(lat, na.rm=TRUE)
yrange <- range(long, na.rm=TRUE)
xbox <- xrange + c(-20000, 20000)
ybox <- yrange + c(-20000, 20000)
#plot your stuff
plot(shapefile, lwd=2)
image(fld, axes=F, add=T)
contour(fld, add=T)
#and here is the magic
polypath(c(lat, NA, c(xbox, rev(xbox))),
c(long, NA, rep(ybox, each=2)),
col="white", rule="evenodd")

Related

Plot connecting lines on a projected map (mapproj, gcIntermediate)

I am unsuccessfully trying to plot lines on a world map with Mollweide projection. I also plotted points on that same map, and it worked out fine. For the lines, I tried to adapt this example to my needs: http://flowingdata.com/2011/05/11/how-to-map-connections-with-great-circles/.
I failed with the pre-test (Step 4 in the ex.) already. In the following code, the line is supposed to connect Kenya and Australia. It runs without errors, but there's no line in the output. (I also tested the example without mapproj and the line is there.)
library("maps")
library("mapproj")
library("geosphere")
map("world",proj="mollweide", orientation= c(90,0,0), fill=TRUE, col="white", bg="lightblue")
lon_ke <- 38
lat_ke <- 1
lon_aus <- 133
lat_aus <- -27
inter <- gcIntermediate(c(mapproject(lon_ke,lat_ke), proj="mollweide", orientation= c(90,0,0)),
c(mapproject(lon_aus,lat_aus), proj="mollweide", orientation= c(90,0,0)),
n=50, addStartEnd=TRUE)
lines(inter)
I found a solution to my problem, based on Thomas Rahlf's book (see comment). Here's my script (it helps visualizing where authors publish articles).
library(maps)
library(geosphere)
library(mapproj)
#load data
locations <- read.csv("articles-authors-locations.csv", header=TRUE, check.names = FALSE)
#plot map with Mollweide projection
myProj.type<-"mollweide"
myProj.orient<-c(90,0,0)
x<-map(proj=myProj.type,orient=myProj.orient,wrap=T,fill=TRUE, col="white", bg="lightblue",xlim=range(locations$ArticleLong),ylim=range(locations$ArticleLat)
)
#plot jittered points for authors' locations
myStartP<-mapproject(jitter(locations$AuthorLong,amount=3),jitter(locations$AuthorLat, amount=1),proj=myProj.type,orient=myProj.orient)
points(myStartP,col="darkblue",pch=20,cex=1)
#set transparent colors
myTColour<-rgb(0,0,0,50,maxColorValue=255)
red_transp <- adjustcolor("red", alpha.f = 0.4)
#plot lines and jittered points, connecting authors' and articles locations
for (i in 1:nrow(locations))
{
myGC1<-gcIntermediate(c(locations$AuthorLong[i],locations$AuthorLat[i]),c(locations$ArticleLong[i],locations$ArticleLat[i]),addStartEnd=T, n=50)
moll<-mapproject(myGC1[,1],myGC1[,2],projection=myProj.type,orientation=myProj.orient)
lines(moll$x,moll$y,lwd=2.5,col=myTColour)
myDestP<-mapproject(
jitter(locations$ArticleLong[i], amount=3),
jitter(locations$ArticleLat[i], amount=1),
proj=myProj.type,orient=myProj.orient)
points(myDestP,col=red_transp,pch=20,cex=1)
}

SpatialLines instead of segments (spplot)

I'd like to use spplot + sp.lines (lattice) instead of plot + segments. Do you know a simple way to realise this, e.g. R: Calculating the shortest distance between two point layers
library(dismo)
require(rgdal)
require(FNN)
laurus <- gbif("Laurus", "nobilis")
locs <- subset(laurus, !is.na(lat) & !is.na(lon),
select = c("country", "lat", "lon"))
locs.uk <- subset(locs, locs$country=="United Kingdom")
locs.ire <- subset(locs, locs$country=="Ireland")
uk_coord <- SpatialPoints(locs.uk[,c("lon","lat")])
ire_coord <- SpatialPoints(locs.ire[,c("lon","lat")])
crs.geo<-CRS("+proj=longlat +ellps=WGS84 +datum=WGS84")
proj4string(uk_coord) <- crs.geo
proj4string(ire_coord) <- crs.geo
uk_coord <- spTransform(uk_coord, CRS("+init=epsg:27700"))
ire_coord <- spTransform(ire_coord, CRS("+init=epsg:27700"))
g = get.knnx(coordinates(uk_coord), coordinates(ire_coord),k=1)
to visualise this
plot(uk_coord, col=2, xlim=c(-1e5,6e5))
plot(ire_coord, add=TRUE)
segments(coordinates(ire_coord)[,1],
coordinates(ire_coord)[,2],
coordinates(uk_coord[g$nn.index[,1]])[,1],
coordinates(uk_coord[g$nn.index[,1]])[,2])
can probably converted to something like
ire <- list("sp.points", ire_coord)
spplot(uk_coord, sp.layout=list(ire))
but is there a easy way to convert segments to SpatialLines i.e. list("sp.lines", Lines(...))
Try panel.segments() from the lattice-package:
library("lattice")
spplot(rbind(uk_coord, ire_coord), auto.key=FALSE,
panel=function(...) {
panel.xyplot(...)
panel.segments(coordinates(ire_coord)[,1],
coordinates(ire_coord)[,2],
coordinates(uk_coord[g$nn.index[,1]])[,1],
coordinates(uk_coord[g$nn.index[,1]])[,2])
})
Understanding panel functions is more powerful than relying on sp.layout in spplot -- and so is using lattice or grid functions directly. The solution with sp.layout could look like this:
spplot(uk_coord, auto.key=FALSE, col.regions = 'black',
sp.layout = list(ire,
list("panel.segments",
coordinates(ire_coord)[,1],
coordinates(ire_coord)[,2],
coordinates(uk_coord[g$nn.index[,1]])[,1],
coordinates(uk_coord[g$nn.index[,1]])[,2])),
xlim = c(-140000,700000))
note that it is not restricted to the sp.lines etc functions; in upcoming sp 1.1-0, quotes around function names can also be omitted.
spplot tries to plot attributes of features in color by default, which is not meaningful here, so what you basically want is an xyplot with controlled aspect ratio (asp="iso").

Geo mapping in R

I have a transaction data at country level.
Data Sample:
TransID CountryOrigin(CO) CountryDestination(CD) COLat COLong CDLat CDLong
1 India Australia 20.593684 78.962880 -25.274398 133.775136
Now i want to link the Country origin and destination with the number of transactions.If the transaction is high then the width of the line will be bigger than the low transaction zone.
I want the visualization more similar to below image
(With the country name label in worldmap)
I am not quite sure, but as far as I understand you are looking for something like this:
http://flowingdata.com/2011/05/11/how-to-map-connections-with-great-circles/
If you want the width of the line bigger in higher transaction zones, you have to set the lwd parameter higher in these lines:
#Load packages
install.packages("maps")
install.packages("geosphere")
library(maps)
library(geosphere)
#Create a Map
xlim <- c(55.593, 140.9628)
ylim <- c(-30.2743, 40.775)
map("world", col="#f2f2f2", fill=TRUE, bg="white", lwd=0.05, xlim=xlim, ylim=ylim)
#create a line
lat_india <- 20.5936
lon_india <- 78.96288
lat_aussie <- -25.2743
lon_aussie <- 133.77
inter <- gcIntermediate(c(lon_india, lat_india), c(lon_aussie, lat_aussie), n=50, addStartEnd=TRUE)
#plot the line (lwd represents the width of the line)
lines(inter, lwd=3)

Overlap image plot on a Google Map background in R

I'm trying to add this plot of a function defined on Veneto (italian region)
obtained by an image and contour:
image(X,Y,evalmati,col=heat.colors(100), xlab="", ylab="", asp=1,zlim=zlimits,main=title)
contour(X,Y,evalmati,add=T)
(here you can find objects: https://dl.dropboxusercontent.com/u/47720440/bounty.RData)
on a Google Map background.
I tried two ways:
PACKAGE RGoogleMaps
I downloaded the map mbackground
MapVeneto<-GetMap.bbox(lonR=c(10.53,13.18),latR=c(44.7,46.76),size = c(640,640),MINIMUMSIZE=TRUE)
PlotOnStaticMap(MapVeneto)
but i don't know the commands useful to add the plot defined by image and contour to the map
PACKAGE loa
I tried this way:
lat.loa<-NULL
lon.loa<-NULL
z.loa<-NULL
nx=dim(evalmati)[1]
ny=dim(evalmati)[2]
for (i in 1:nx)
{
for (j in 1:ny)
{
if(!is.na(evalmati[i,j]))
{
lon.loa<-c(lon.loa,X[i])
lat.loa<-c(lat.loa,Y[j])
z.loa<-c(z.loa,evalmati[i,j])
}
}
}
GoogleMap(z.loa ~ lat.loa*lon.loa,col.regions=c("red","yellow"),labels=TRUE,contour=TRUE,alpha.regions=list(alpha=.5, alpha=.5),panel=panel.contourplot)
but the plot wasn't like the first one:
in the legend of this plot I have 7 colors, and the plot use only these values. image plot is more accurate.
How can I add image plot to GoogleMaps background?
If the use of a GoogleMap map is not mandatory (e.g. if you only need to visualize the coastline + some depth/altitude information on the map), you could use the package marmap to do what you want. Please note that you will need to install the latest development version of marmap available on github to use readGEBCO.bathy() since the format of the files generated when downloading GEBCO files has been altered recently. The data from the NOAA servers is fine but not very accurate in your region of interest (only one minute resolution vs half a minute for GEBCO). Here is the data from GEBCO I used to produce the map : GEBCO file
library(marmap)
# Get hypsometric and bathymetric data from either NOAA or GEBCO servers
# bath <- getNOAA.bathy(lon1=10, lon2=14, lat1=44, lat2=47, res=1, keep=TRUE)
bath <- readGEBCO.bathy("GEBCO_2014_2D_10.0_44.0_14.0_47.0.nc")
# Create color palettes for sea and land
blues <- c("lightsteelblue4", "lightsteelblue3", "lightsteelblue2", "lightsteelblue1")
greys <- c(grey(0.6), grey(0.93), grey(0.99))
# Plot the hypsometric/bathymetric map
plot(bath, land=T, im=T, lwd=.03, bpal = list(c(0, max(bath), greys), c(min(bath), 0, blues)))
plot(bath, n=1, add=T, lwd=.5) # Add coastline
# Transform your data into a bathy object
rownames(evalmati) <- X
colnames(evalmati) <- Y
class(evalmati) <- "bathy"
# Overlay evalmati on the map
plot(evalmati, land=T, im=T, lwd=.1, bpal=col2alpha(heat.colors(100),.7), add=T, drawlabels=TRUE) # use deep= shallow= step= to adjust contour lines
plot(outline.buffer(evalmati),add=TRUE, n=1) # Outline of the data
# Add cities locations and names
library(maps)
map.cities(country="Italy", label=T, minpop=50000)
Since your evalmati data is now a bathy object, you can adjust its appearance on the map like you would for the map background (adjust the number and width of contour lines, adjust the color gradient, etc). plot.bath() uses both image() and contour() so you should be able to get the same results as when you plot with image(). Please take a look at the help for plot.bathy() and the package vignettes for more examples.
I am not realy inside the subject, but Lovelace, R. "Introduction to visualising spatial data in R" might help you
https://github.com/Robinlovelace/Creating-maps-in-R/raw/master/intro-spatial-rl.pdf From section "Adding base maps to ggplot2 with ggmap" with small changes and data from https://github.com/Robinlovelace/Creating-maps-in-R/archive/master.zip
library(dplyr)
library(ggmap)
library(rgdal)
lnd_sport_wgs84 <- readOGR(dsn = "./Creating-maps-in-R-master/data",
layer = "london_sport") %>%
spTransform(CRS("+init=epsg:4326"))
lnd_wgs84_f <- lnd_sport_wgs84 %>%
fortify(region = "ons_label") %>%
left_join(lnd_sport_wgs84#data,
by = c("id" = "ons_label"))
ggmap(get_map(location = bbox(lnd_sport_wgs84) )) +
geom_polygon(data = lnd_wgs84_f,
aes(x = long, y = lat, group = group, fill = Partic_Per),
alpha = 0.5)

Shapefile and vector file don't precisely overlap when plotted

I want to plot a shapefile over a raster file in R but I can't make them overlap perfectly: the raster appears to be rotated of few degrees counter-clockwise. Is it a problem with the projection?
Please consider the following MWE
library(raster)
library(rgdal)
# Download from http://biogeo.ucdavis.edu/data/gadm2/shp/ITA_adm.zip
shape_file = "ITA_adm1.shp"
# Download from http://sedac.ciesin.columbia.edu/data/set/gpw-v3-population-density/data-download
# Setting Geography: Country, Italy; Data Attributes: Grid
pop_density_file ="w001001.adf"
italy_map <- readOGR(dsn = shape_file, layer = "ITA_adm1")
italy_map_dens <- raster(pop_density_file)
colPal <- colorRampPalette(c("white", "red"))( 500 )
par(mar=c(0,0,0,0))
plot(italy_map_dens, xlim = c(6.70, 18.32), ylim = c(35.2, 47.6), axes=FALSE, box=FALSE, legend=FALSE, col=colPal)
plot(italy_map, xlim = c(6.70, 18.32), ylim = c(35.2, 47.6), border="grey", add=TRUE)
Apparently there was a bug in the rgdal package. My problem was solved after I updated it to version 0.8-12.
It does appear to be a problem with the projection. You need to find out the exact projection of both datasets, and convert one of the datasets to the projection of the other dataset.

Resources