Drawing line on ggmap plot between two countries using long/lat - r

I am a total newbie to R and I would like to draw a line (possibly weighted, e.g., by the number of trips made) between two countries. Currently, I use longitude and latitude for each capital to draw a line, but I would like to do it using the package ggmap. I was looking around, but did not find any solution so far. I would appreciate a quick help.
require(ggmap)
require (rworldmap)
all_content = readLines("ext_lt_intratrd_1_Data.csv")
skip_second = all_content[-2]
dat = read.csv(textConnection(skip_second), header = TRUE, stringsAsFactors =F)
dat[5,2]<- c("Germany") # using a data where the first line is
header, but second line must be skipped as it is EU 27
and not a single country
europe <- read.csv("eulonglat.csv", header = TRUE) # using world capitals to
generate points
myfulldata <- merge(dat, europe)
map <- get_map(location = 'Europe', zoom = 4)
mapPoints <- ggmap(map) + geom_point(aes(x = UNc_longitude, y = UNc_latitude, size
= log(myfulldata$Value)), data = myfulldata, col = "red", alpha= 0.5) # this can
be plotted
# i would continue with drawing line and i searched for references
# i found arrows(42.66,23.34,50.82,4.47) - which did not work
# i tried to look for a reference work more, but could not find
# instead i found it using with the package rworldmap the following
lines(c(4.47, 23.32), c(50.82, 42.66))
# this does not work on ggmap

Related

Exporting a contoured Kernel density estimation plot to raster or shapefile format

I'm trying to perform Kernel density estimation in R using some GPS data that I have. My aim is to create a contoured output with each line representing 10% of the KDE. From here i want to import the output (as a shapefile or raster) into either QGIS or arcmap so I can overlay the output on top of existing environmental layers.
So far i have used AdehabitatHR to create the following output using the below code:
kud<-kernelUD(locs1[,1], h="href")
vud<-getvolumeUD(kud)
vud <- estUDm2spixdf(vud)
xyzv <- as.image.SpatialGridDataFrame(vud)
contoured<-contour(xyzv, add=TRUE)
Aside from being able to remove the colour, this is how i wish the output to appear (or near to). However i am struggling to figure out how i can export this as either a shapefile or raster? Any suggestions would be gratefully received.
With the amt package this should be relatively straightforward:
library(adehabitatHR)
library(sf)
library(amt)
data("puechabonsp")
relocs <- puechabonsp$relocs
hr <- as.data.frame(relocs) %>% make_track(X, Y, name = Name) %>%
hr_kde(trast = raster(amt::bbox(., buffer = 2000), res = 50)) %>%
hr_isopleths(level = seq(0.05, 0.95, 0.1))
# Use the sf package to write a shape file, or any other supported format
st_write(hr, "~/tmp/home_ranges.shp")
Note, it is also relatively easy to plot
library(ggplot2)
ggplot(hr) + geom_sf(fill = NA, aes(col = level))

Draw boundaries using groups and order for each region gg_map Rgooglemaps

I'm trying to plot custom boundaries (dma's) into a google map.
library(ggmap)
library(ggplot2)
US <- get_map(location = c(-95.7129,37.0902),zoom = 3)
US_map <- ggmap(US)
then using the following CSV file with the coordinates groups and order
https://www.dropbox.com/s/3xv192k5401np4r/DMAs%20coordinates%20sample.csv?dl=0
Then I can plot the coordinates using dots:
smpl <- read.csv('DMAs coordinates sample.csv')
US_map + geom_point(data=smpl,aes(x=Longitude, y=Latitude),size=0.01)
But I would like to plot lines connected by these dots using the path from point_order and group each set of lines using dma_boundary.UniqueID I'm sure there's a way to do this. but I cannot find the right way.
I found a way to do this,
Using geom_path for each group represented by dma_boundaty.UniqueID
As the data is already sorted by sub_polygon_id and point_order we use geom_path to use the order set in data. Then,
library(ggplot2)
library(data.table)
library(ggmap)
dma_boundaty <- data.table(read.csv('.../path')
US <- get_map(location = c(-95.7129,37.0902),zoom = 3)
US_map <- ggmap(US)
dma_map <- US_map + lapply(0:205,function(i) {
geom_path(data=dma_boundary[dma_boundary.UniqueID == i,],aes(x=Longitude, y=Latitude))})

Spatial data overlay selection in R

I'm trying to overlay some spatial data from a bigger SpatialPolygonsDataFrame (world size) to a smaller (country size), by doing these:
x <- c("rgdal", "dplyr",'ggplot2')
apply(x, library, character.only = TRUE)
est<-readOGR(dsn='/estados_2010',layer='estados_2010')
est_f<-fortify(est)
est$id<-row.names(est)
est_f<-left_join(est_f,est#data)
zon<-readOGR(dsn='/Zonas Homogeneas/gyga_ed_poly.shp',layer='gyga_ed_poly')
zon_f<-fortify(zon)
zon$id<-row.names(zon)
zon_f<-left_join(zon_f,zon#data)
t<-ggplot()+geom_polygon(data=zon_f,aes(x=long,y=lat,group=group,fill=GRID_CODE))
t+geom_polygon(data=est_f,aes(x=long,y=lat,group=group),fill=NA,color='red')+coord_fixed(xlim=est_f$long,ylim=est_f$lat,1)
Which is resulting in this:
I'm want to select only what is being plotted inside the polygon with the red lines.
If someone could help me with this issue, I'll appreciate
PS.: For those who want to reproduce the example completely by yourselves, the files are available in the links above to my google drive:
https://drive.google.com/open?id=0B6XKeXRlyyTDakx2cmJORlZqNUE
Thanks in advance.
Since you are using polygons to display the raster values, you can use a spatial selection via [ like in this reproducible example:
library(raster)
library(rgdal)
bra <- getData("GADM", country = "BRA", level = 1)
r <- getData("worldclim", res = 10, var = "bio")
r <- r[[1]]
r <- crop(r, bra)
r <- rasterToPolygons(r)
# bra and raster (now as polygons) have to have the same projection, thusly reproject!
bra <- spTransform(bra, CRSobj = proj4string(r))
here comes the magic!!
r <- r[bra, ]
let's look at the results:
library(ggplot2)
t <- ggplot()+
geom_polygon(data=r,aes(x=long,y=lat,group=group, fill = rep(r$bio1, each = 5)))
t +
geom_polygon(data=bra,aes(x=long,y=lat,group=group),fill=NA,color='red') + coord_map()

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)

How to add continuous color legend to an R map made with maps

I'm using the R code shown below, which loads libraries maps and RColorBrewer, to create a map of the world with countries color-coded by population rank. As you can see in the image below, I'm using a green palette in which the darker the green, the larger the population.
I'd like to add a continuous color legend showing the full palette to denote that light green = small population and dark green = large population, but I can't find a way to do it via maps. Could you tell me what is the easiest way to add a continuous color legend (or color key/color scale) to my map?
# Load libraries
library(maps)
library(RColorBrewer)
# Load world data
data(world.cities)
# Calculate world population by country
world.pop = aggregate(x=world.cities$pop, by=list(world.cities$country.etc),
FUN=sum)
world.pop = setNames(world.pop, c('Country', 'Population'))
# Create a color palette
palette = colorRampPalette(brewer.pal(n=9, name='Greens'))(nrow(world.pop))
# Sort the colors in the same order as the countries' populations
palette = palette[rank(-world.pop$Population)]
# Draw a map of the world
map(database='world', fill=T, col=palette, bg='light blue')
The world map in the maps package is about 30 years old (e.g., has USSR & Yugoslavia).
Plus you have a glitch in your code that causes the overpopulated Greenland that #Jealie noticed (and India is less populated than Antarctica).
You can create a continuousish legend with a modern world using rworldmap.
library(rworldmap)
library(RColorBrewer)
#get a coarse resolution map
sPDF <- getMap()
#using your green colours
mapDevice('x11') #create a map shaped device
numCats <- 100 #set number of categories to use
palette = colorRampPalette(brewer.pal(n=9, name='Greens'))(numCats)
mapCountryData(sPDF,
nameColumnToPlot="POP_EST",
catMethod="fixedWidth",
numCats=numCats,
colourPalette=palette)
You can alter the legend adding more labels etc. by doing something like this :
mapParams <- mapCountryData(sPDF, nameColumnToPlot="POP_EST", catMethod="pretty", numCats=100, colourPalette=palette, addLegend=FALSE)
#add a modified legend using the same initial parameters as mapCountryData
do.call( addMapLegend, c( mapParams
, legendLabels="all"
, legendWidth=0.5
))
Just briefly to explore the glitch in your code. It occurs because you create a palette for the number of countries in world.cities (239) and then apply it to the number of polygons in the world database from maps (2026). So it probably gets recycled and the colours of your countries have no relation to population. The code below demonstrates the source of your problem.
#find the countries used in the maps world map
mapCountries <- unique( map('world',namesonly=TRUE) )
length(mapCountries)
#[1] 2026
#exclude those containing ':' e.g. "USA:Alaska:Baranof Island"
mapCountries2 <- mapCountries[-grep(':',mapCountries)]
length(mapCountries2)
#[1] 186
#which don't match between the map and world.cities ?
#cityCountries <- unique( world.cities$country.etc )
cityCountries <- world.pop$Country
length(cityCountries)
#[1] 239
#which countries are in the map but not in world.cities ?
mapCountries2[ is.na(match(mapCountries2,cityCountries)) ]
#includes USSR, Yugoslavia & Czechoslovakia
Within the library SDMTools there is the function legend.gradient
adding this code to the end of your code should give the desired result:
# Draw a map of the world
map(database='world', fill=T, col=palette, bg='light blue')
x = c(-20, -15, -15, -20)
y = c(0, 60, 60, 0)
legend.gradient(cbind(x = x - 150, y = y - 30),
cols = brewer.pal(n=9, name='Greens'), title = "TITLE", limits = "")
You will need to fiddle with the x & y coordinates to get the legend into the desired location however.
EDIT
The x and y coordinates also adjust the shape of the box so I changed the code so that the box shape would not change if you only alter the numbers within the legend.gradient function. Below is what this code should produce

Resources