ggplot2 map is blank - r

I am using similar to code to other scripts with different shape files from Statistics Canada. However, I can't get a simple script to work with a provincial map. I think the problem is simple but I can't see it.
setwd("D:\\OneDrive\\lfs_stuff")
project_folder<-getwd()
data_folder<-project_folder
library(tidyverse)
#now start the map
library(rgeos)
library(rgdal)
library(maptools)
library(sp)
library(mapproj)
library(ggplot2)
#get test data
mydata<-read_csv("map_data.csv",col_types=list(col_character(),col_double()))
print(mydata)
# shape file came from this link for a digital shape file
# http://www12.statcan.gc.ca/census-recensement/2011/geo/bound-limit/files-fichiers/2016/lpr_000a16a_e.zip
target_url<-"http://www12.statcan.gc.ca/census-recensement/2011/geo/bound-limit/files-fichiers/2016/lpr_000a16a_e.zip"
url_file<-"lpr_000a16a_e.zip"
download_target<-paste0(project_folder,"/",url_file)
download.file(target_url,download_target,mode="wb",quiet=FALSE)
unzip(download_target,overwrite=TRUE,exdir=data_folder)
provincial_shape_file<-gsub(".zip",".shp",download_target)
provincial_shp<-readOGR(dsn=provincial_shape_file,layer="lpr_000a16a_e")
#convert it to the reqired data structure. the id vbl will contain the provincial codes
prov_base_map<-fortify(provincial_shp,region="PRUID")
map_data_1<-merge(prov_base_map,as_data_frame(mydata),by="id")
map1<-ggplot()+
geom_map(data=map_data_1,map=map_data_1,stat="identity",
aes(map_id=id,x=long,y=lat,fill=(pch),group=group),
colour="black",size=0.3)+
coord_map()
print(map1)
The download for the shape file is in the script. The mydata file is shown below
"id","pch"
"10",0.667259786476859
"11",5.63186813186813
"12",2.12053571428572
"13",-0.563697857948142
"24",0.150669774230772
"35",1.15309092428315
"46",0.479282622139765
"47",1.70242950877815
"48",1.84482533036765
"59",1.96197656978394

Here's one way with sf (though I think the ultimate issue is not having the id being identified correctly):
library(sf)
library(httr)
library(tidyverse)
read.csv(text='"id","pch"
"10",0.667259786476859
"11",5.63186813186813
"12",2.12053571428572
"13",-0.563697857948142
"24",0.150669774230772
"35",1.15309092428315
"46",0.479282622139765
"47",1.70242950877815
"48",1.84482533036765
"59",1.96197656978394',
stringsAsFactors=FALSE,
colClasses = c("character", "double")) -> xdf
# cross-platform-friendly d/l with caching built-in
try(httr::GET(
url = "http://www12.statcan.gc.ca/census-recensement/2011/geo/bound-limit/files-fichiers/2016/lpr_000a16a_e.zip",
httr::write_disk("~/Data/lpr_00a16a_e.zip"),
httr::progress()
)) -> res
fils <- unzip("~/Data/lpr_00a16a_e.zip", exdir = "~/Data/lpr")
ca_map <- st_read(grep("shp$", fils, value=TRUE), stringsAsFactors = FALSE)
ca_map <- st_simplify(ca_map, TRUE, 10) # you don't need the coastlines to be that detailed
ca_map <- left_join(ca_map, xdf, by=c("PRUID"="id"))
ggplot(ca_map) +
geom_sf(aes(fill = pch)) +
viridis::scale_fill_viridis(direction=-1, option="magma") +
coord_sf()
As an aside, even though I simplified the shapefile (for faster plotting) I'd hunt around for a light[er]-weight GeoJSON version of the provinces since the one you grabbed has super fine-grained coastlines and you absolutely don't need that for a choropleth.

Related

Extract CMIP6 information with R

I'm doing a research about climate change and I want to extract the CMIP6 information using R but I don't get the results I want. This is the code.
library(raster)
library(ncdf4)
long_lat <- read.csv("C:/Users/USUARIO/Desktop/Tesis/Coordenadas - copia.csv", header = T)
raster_pp <- raster::brick("pr_day_ACCESS-CM2_historical_r1i1p1f1_gn_2000.nc")
sp::coordinates(long_lat) <- ~XX+YY
raster::projection(long_lat) <- raster::projection(raster_pp)
points_long_lat <- raster::extract(raster_pp[[1]], long_lat, cellnumbers = T)[,1]
data_long_lat <- t(raster_pp[points_long_lat])
The cordinates I've used are the following: -77.7754,-9.5352 (latitude, longitude), but I've tried these as well and still doesn't work 102.2246,-9.5352. Thanks for your response.

R - How do I read Shapefiles in from geojson API?

I am used to reading in shapefiles in Python with the following simple code:
import geopandas
url='https://opendata.arcgis.com/datasets/01fd6b2d7600446d8af768005992f76a_3.geojson'
gdf = geopandas.read_file(url)
I am trying to do it in R so that people do not have to download the shapefiles, but I am struggling.
I have tried this, but getting 'cannot open data source' error:
sp <- readOGR(dsn="https://opendata.arcgis.com/datasets/01fd6b2d7600446d8af768005992f76a_3.geojson", layer="OGRGeoJSON")
If I download the shapefile, my code looks like this:
#load shape file
shape_file_name<- "D:/Users/XXX/Documents/R/NUTS_Level_2_January_2018_Generalised_Clipped_Boundaries_in_the_United_Kingdom.shp"
#import the shape file
shape_file <- readOGR(shape_file_name, stringsAsFactors = F)
#fortify shapefile
shp <- fortify(shape_file)
#creates the NUTS map
NUTS_map <- ggplot() +
geom_polygon(data = shp,
aes(x = long, y = lat, group = group),
color = 'lightsteelblue', fill = 'lightcyan', size = .9) +coord_fixed(1.7)+ theme_void()
I just want to replace the following lines:
shape_file_name<- "D:/Users/XXX/Documents/R/NUTS_Level_2_January_2018_Generalised_Clipped_Boundaries_in_the_United_Kingdom.shp"
shape_file <- readOGR(shape_file_name, stringsAsFactors = F)
With a call to the API found at the following webpage:
https://geoportal.statistics.gov.uk/datasets/nuts-level-2-january-2018-names-and-codes-in-the-united-kingdom
Many thanks
st_read from the sf-package works fine for me.
#load library
library(sf)
#load geojson from url
data <- st_read('https://opendata.arcgis.com/datasets/01fd6b2d7600446d8af768005992f76a_3.geojson')
#quick view to see what we're dealing with
mapview::mapview(data)

How to merge a shapefile with a .csv and create a graph

I am trying to merge a shapefile and .csv file to make a map of election results. I can make a graph when I load the shapefile, but as soon as I merge it with the .csv, it says "Error in plot.window(...) : need finite 'xlim' values".
I have been reading online, and I think maybe I have to merge the csv file to the shapefile (I have been merging the shapefile to the csv file). However, the csv file (which contains the election results) has more values than the shapefile (which gives the coordinates for the districts). How can I create more districts to match the election results? And will this even solve my problem, or is there something else that I am missing? Also, the data is in spanish, but the relevant values Distritos=districts, partidos=political party, cargo=type of election, votos=votes.
library(maptools)
library(rgdal)
library(rgeos)
library(sf)
municipios <-readOGR("/Users/Desktop/Limite_partidos/Shapefile/Partidos.shp")
elec <- read.csv("/Users/Desktop/elections excel.csv", header = TRUE, stringsAsFactors = FALSE)
library(dplyr)
#merge datasets together
elec <-merge(elec, municipios, by=c("nam"), na.rm=TRUE)
plot(elec)
Link to election results (elec)
Link for shapefile (municipios)
First some sample data. This should be similar to what you get when
you read in your shapefile. The R spatial object is called a
SpatialPolygonsDataFrame. It carries a data.frame with the covariate
information about your polygons.
library(sp)
Sr1 <- Polygon(cbind(c(2,4,4,1,2),c(2,3,5,4,2)))
Sr2 <- Polygon(cbind(c(5,4,2,5),c(2,3,2,2)))
Sr3 <- Polygon(cbind(c(4,4,5,10,4),c(5,3,2,5,5)))
Sr4 <- Polygon(cbind(c(5,6,6,5,5),c(4,4,3,3,4)), hole = TRUE)
Srs1 <- Polygons(list(Sr1), "s1")
Srs2 <- Polygons(list(Sr2), "s2")
Srs3 <- Polygons(list(Sr3, Sr4), "s3/4")
SpP <- SpatialPolygons(list(Srs1,Srs2,Srs3), 1:3)
Spdf <- SpatialPolygonsDataFrame(SpP, data.frame(name = c("a", "b", "c"), row.names = c("s1", "s2", "s3/4")))
Now you have a spatial object that you can plot:
plot(Spdf)
and have a look at the attached data.frame of your spatial object. Here you need to have some identifier that you will match to your election results:
Spdf#data
You also have another dataframe with your 'election results' (Also with this identifier)
election <- data.frame(name = c("a", "c", "b"), voted = c(0.1, 0.2, 0.3))
Now match in the election results to you spatial object so you can plot it:
Spdf#data$voted <- election$voted[match(Spdf$name, election$name)]
To plot the polygons with the voted result as the colour of the polygon you need a pallette:
Spdf#data$colour <- heat.colors(3)[as.numeric(cut(Spdf#data$voted, 3))]
Then just plot:
plot(Spdf, col = Spdf#data$colour)
You can image that you will want to have more than 3 breaks in you
scale and you'll have more polygons but this is just an example. Good luck!
You can either select a single party (and then have a single value per administrative region) or facet by the party (and have as many small multiples as there are parties).
This really depends on what is your aim with the visualization. Given that there seems to be 48 results in your file the "small" multiples would be rather large, and filtering makes more sense.
For joining the shapefile and data frame with election results I suggest using one of the *_join functions from tidyverse package.
Consider this approach, built on assumption of filtering:
library(tidyverse)
library(sf)
tf_elec <- tempfile(fileext = ".csv") # create a temporary csv file
download.file("https://catalogo.datos.gba.gob.ar/dataset/1ae289f8-532c-4f69-a3c8-0268fe0ee390/resource/f8168491-4c38-4b03-82f1-b05fe43f8349/download/generales-2017.csv", tf_elec, quiet = T)
elec <- read_csv2(tf_elec) # read the data
tf_zip <- tempfile(fileext = ".zip") # a temoprary zip file
download.file("https://catalogo.datos.gba.gob.ar/dataset/627f65de-2510-4bf4-976b-16035828b5ae/resource/de607a34-b782-420f-93ed-35073a016e01/download/limite_partidos.zip", tf_zip, quiet = T)
unzip(tf_zip, files = 'Limite_partidos/GeoJSON/Partidos.geojson', exdir = tempdir(), junkpaths = T)
municipios <- st_read(paste0(tempdir(), '/Partidos.geojson'), quiet = T) # read the metro stations
src <- municipios %>%
left_join(elec, by = c('nam' = 'distrito')) %>%
filter(partido == 'VOTOS NULOS') #or what not... :)
ggplot() +
geom_sf(data = src, aes(fill = votos))
The most difficult part is downloading the data. The left_join() is in the second last chunk, and the very last is visualization - for the sake of simplicty I took the easy ggplot2 route, but also consider the excellent tmap package if you want your maps to really shine.

Trouble merging shapefiles in R

I am having trouble merging shapefiles in R. Here is my code thus far:
library(rgdal)
library(maptools)
library(gridExtra)
setwd("/Users/Cornelius/Dropbox/Cornelius_Sharedfolder")
#Load a geodatabase
fgdb = "/Users/Cornelius/Dropbox/Cornelius_Sharedfolder/RwandaGDB.gdb"
subset(ogrDrivers(), grepl("GDB", name))
fc_list = ogrListLayers(fgdb)
print(fc_list)
#Get the shapefiles from the geodatabase:
Residence=readOGR(dsn=fgdb, layer="RĂ©sidence")
Territoire = readOGR(dsn=fgdb,layer="Territoire")
Chefferie=readOGR(ds=fgdb, layer="Chefferie")
Sous_Chefferie=readOGR(ds=fgdb, layer="Sous_Chefferie")
RwandaPre2002=readOGR(ds=fgdb, layer="RwandaPre2002")
Country_Boundary2012=readOGR(ds=fgdb, layer="Country_Boundary2012")
Province_Boundary2012=readOGR(ds=fgdb, layer="Province_Boundary2012")
Sector_Boundary2012=readOGR(ds=fgdb, layer="Sector_Boundary2012")
District_Boundary2012=readOGR(ds=fgdb, layer="District_Boundary2012")
Cell_Boundary2012=readOGR(ds=fgdb, layer="Cell_Boundary2012")
x = list(Residence, Territoire, Sous_Chefferie, RwandaPre2002, Country_Boundary2012, Province_Boundary2012, Sector_Boundary2012, District_Boundary2012, Cell_Boundary2012)}
This all goes fine. However, when I try to merge two shapefiles - for example, Residence and Territoire, and use the following code, it gives me an error:
test_bind <-spRbind(Territoire, Residence)
The error says: "non-unique polygon IDs."
I'm not sure what this means. Could you please help?

Mapping the world on ggplot2

I've been trying to plot a map of the world on ggplot2. I followed the threads of emails: ggplot map with l but I do run into the same error message and I don't understand the author comments on how to fix it.
library(rgdal)
library(ggplot2)
library(maptools)
library(sp)
gpclibPermit()
world.map <- readOGR(dsn="data", layer="TM_WORLD_BORDERS_SIMPL-0.3")
world.ggmap <- fortify(world.map, region = "NAME")
> world.ggmap <- fortify(world.map, region = "NAME")
Error in nchar(ID) : invalid multibyte string 1
So, I followed the instructions here, more or less, to create this world map:
library(ggplot2)
library(cshapes)
world <- cshp(date=as.Date("2008-1-1"))
world.points <- fortify(world, region='COWCODE')
p <- ggplot(world.points, aes(long,lat,group=group)) + geom_polygon()
p
It looks like it takes some more work to combine this with data, e.g. for a thematic map, but the post above goes through this in detail.
Not sure if you still need an answer to this, but I hope it's helpful to someone in any case.

Resources