I would need to draw, in R the map of the European Union and a shaded circle that overlaps it. The circle should have a center at a point with known longitude and latitude and a predetermined radius.
First, I can't even draw the map, even though the code doesn't throw out any errors. The code is:
library(ggplot2)
library(grid)
library(rworldmap)
# Get the world map
worldMap <- getMap()
# Member States of the European Union
europeanUnion <- c("Austria","Belgium","Bulgaria","Croatia","Cyprus",
"Czech Rep.","Denmark","Estonia","Finland","France",
"Germany","Greece","Hungary","Ireland","Italy","Latvia",
"Lithuania","Luxembourg","Malta","Netherlands","Poland",
"Portugal","Romania","Slovakia","Slovenia","Spain",
"Sweden")
# Select only the index of states member of the E.U.
indEU <- which(worldMap$NAME%in%europeanUnion)
# Extract longitude and latitude border's coordinates of members states of E.U.
europeCoords <- lapply(indEU, function(i){
df <- data.frame(worldMap#polygons[[i]]#Polygons[[1]]#coords)
df$region =as.character(worldMap$NAME[i])
colnames(df) <- list("long", "lat", "region")
return(df)
})
europeCoords <- do.call("rbind", europeCoords)
value <- sample(x = seq(0,3,by = 0.1), size = length(europeanUnion),
replace = TRUE)
europeanUnionTable <- data.frame(country = europeanUnion, value = value)
europeCoords$value <- europeanUnionTable$value[match(europeCoords$region,europeanUnionTable$country)]
P <- ggplot() + geom_polygon(data = europeCoords, aes(x = long, y = lat, group = region, fill =
value),
colour = "black", size = 0.1) +
coord_map(xlim = c(-13, 35), ylim = c(32, 71))
How can I fix the problem and add the circle?
Thank you!
You might want to consider using the sf (simple features) package to work with geographic data.
Below is code to map the countries you've specified, and to plot a circle centered in Germany. You may need to crop or filter the data, as there are a few EU landmasses far outside what most consider 'Europe'.
The circle turns out a bit wonky due to the projection over a large area.
library(ggplot2)
library(grid)
#library(rworldmap)
library(sf)
#> Linking to GEOS 3.8.0, GDAL 3.0.4, PROJ 6.3.1
library(dplyr)
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
# Member States of the European Union
europeanUnion <- c("Austria","Belgium","Bulgaria","Croatia","Cyprus",
"Czech Rep.","Denmark","Estonia","Finland","France",
"Germany","Greece","Hungary","Ireland","Italy","Latvia",
"Lithuania","Luxembourg","Malta","Netherlands","Poland",
"Portugal","Romania","Slovakia","Slovenia","Spain",
"Sweden")
library(rnaturalearth)
world_map <- ne_countries(scale = 50, returnclass = 'sf')
europe_map <- world_map %>% filter(name %in% europeanUnion)
circle <- st_as_sfc(st_bbox(europe_map %>% filter(name == 'Germany'))) %>%
st_transform(3035)%>% ## <- change projection to one in meters
st_centroid() %>% ## centroid point of the bounding box of germany
st_buffer(dist = 1e6) ## <- 1 million meters
p <- ggplot() +
geom_sf(data = europe_map, fill = 'orange') +
geom_sf(data = circle, fill = 'black', alpha = .2) +
theme_void()
p
Created on 2020-10-27 by the reprex package (v0.3.0)
Edit addressing questions in comment:
# make a point for frankfurt:
frankfurt <- st_point(x = c(8.6821, 50.1109)) %>% ## coords from google
st_geometry()
# 1896km buffer (circle) around frankfurt
frankfurt_circle_1896 <- frankfurt %>%
st_set_crs(4326) %>%
st_transform(3035) %>%
st_buffer(dist = 1896000) ## 1896km in m
## Crop the europe map, removing French Guana, etc.
## change x&y coords as needed, these are approximations
europe_bbox <- st_bbox(c(xmin = -12, xmax = 34, ymax = 71, ymin = 34), crs = st_crs(4326))
europe_map_cropped <- europe_map %>%
st_crop(europe_bbox)
# plotting
p2 <- ggplot() +
geom_sf(data = europe_map_cropped, fill = 'orange') +
geom_sf(data = frankfurt_circle_1896, alpha = .2, fill = 'black')
p2
Related
I have a dataset with several hundred geographical points expressed as lat/long values that I plot as dots using tm_dots, on top of some boundaries that I plot using tm_shape (both using tmap).
Does anyone know of a way that I can draw polygons to represent areas within the boundaries of the underlying layer that are not within 500 metres of any of the points plotted? I'd be happy to use other R mapping resources (e.g. ggplot/ggmap) if better for this task.
Current code is:
#Call necessary packages
library(tidyverse)
library (readxl)
library(maptools)
library(classInt)
library(RColorBrewer)
library(sf)
library(tmap)
library(scales)
library(tmaptools)
library(geodata)
#Read in boundary polygon data
#This shape file is from https://www.data.gov.uk/dataset/2cf1f346-2f74-4c06-bd4b-30d7e4df5ae7/middle-layer-super-output-area-msoa-boundaries
shp_name <- "//ims.gov.uk//homedrive//users//JW2002//My Documents//Data//Demography, Mapping & Lookups//Shape Files//East of England//MSOA//Middle_Layer_Super_Output_Areas_December_2011_Generalised_Clipped_Boundaries_in_England_and_Wales.shp"
EofEMSOAs <- st_read(shp_name)%>%
st_as_sf()
#Read deprivation data from another source (not specifically relevant to the mapping section of this project but provides list for subsequent subset to East of England MSOAs only)
EofEMSOAsIMD <- read_excel("~/Data/Demography, Mapping & Lookups/IoD/National & EofE IoD 2019/National&IoD 2019 MSOAs.xlsx",
sheet = "East of England MSOAs")
#Subset MSOA list to East of England Only
EofEMSOAsCodeListOnly <- dplyr::pull(EofEMSOAsIMD, "Area Code")
EofEMSOAsCodeListOnly <- paste(EofEMSOAsCodeListOnly, collapse = '|')
EofEMSOAsFinalList <- EofEMSOAs[grep(EofEMSOAsCodeListOnly, EofEMSOAs$msoa11cd),]
#Generate point data
PointData <- read.table(textConnection("ID Latitude Longitude
A 52.9742585 0.5526301
B 52.972643 0.8495693
C 52.972643 0.8495693
D 51.46133804 0.36403501"), header=TRUE)
#Geocode the point list
PointDataPlotted = st_as_sf(PointData, coords = c('Longitude', 'Latitude'), crs = 4326)
#Remove geometry
PointDataPlotted2 <- PointDataPlotted %>%
as.data.frame() %>%
mutate(buffer = st_buffer(geometry, dist = 5000)) %>%
select(-geometry) %>%
st_as_sf()
#Create union shape of polygons
union <- st_union(EofEMSOAsFinalList)
# generate bounding box
mask_union <- union %>% as_tibble() %>%
mutate(bbox = st_as_sfc(st_bbox(c(xmin = -5.5, xmax = 9, ymax = 51.5, ymin = 42), crs = st_crs(4326)))) %>%
st_as_sf()
# compute difference between bounding box and union polygon to
# use as mask in the final layer
diff <- st_difference(mask_union$bbox, mask_union$geometry)
# Build map
OutputMap <-
# plot only shapes filled red
tm_shape(EofEMSOAsFinalList) +
tm_fill(col = "red") +
# plot only buffer zones of each point in green
tm_shape(PointDataPlotted2)+
tm_fill(col = "forestgreen") +
# add mask
tm_shape(diff) +
tm_fill(col = "white") +
# plot borders of shape
tm_shape(EofEMSOAsFinalList) +
tm_borders(col = "white",
lwd = 1,
lty = "solid") +
# add custom legend
tm_add_legend(type = "symbol",
labels = c("Restricted", "Public"),
col = c("red", "forestgreen"),
title = "Access type",
size = 1.5,
shape = 21)
Here's a solution to find areas within the boundaries of the underlying layer that are within 50 km of any of the points plotted.
library(tidyverse)
library(sf)
library(geodata)
# example polygons of France
polygon <- gadm(country = "FRA", level = 1, path = tempdir()) %>%
st_as_sf() %>%
filter(NAME_1 != "Corse")
# get 100 sample points within union shape of polygons
set.seed(42)
union <- st_union(polygon)
points <- st_sample(x = union, size = 100, type = "random") %>%
as.data.frame() %>%
mutate(id = row_number()) %>% # add an id for later joining
st_as_sf() %>%
# calculate aound each point a buffer zone of 50km
mutate(buffer = st_buffer(geometry, dist = 50000))
# add for each point the polygon (state) in which it is located
points <- st_join(points, polygon, join = st_within) %>%
as.data.frame() %>%
dplyr::select(id, NAME_1) %>%
left_join(points) %>%
filter(NAME_1 != "Corse")
# for each polygon calculate the union shapes of the
# corresponding buffers zones within
points_buff_union <- points %>%
dplyr::select(-geometry) %>%
st_as_sf() %>%
group_by(NAME_1) %>%
summarise()
# plot content
polygon %>%
ggplot() +
geom_sf(data = points_buff_union, aes(geometry = buffer, fill = NAME_1)) +
geom_sf(fill = NA) +
scale_fill_brewer(palette = "Paired") +
geom_sf(data = points, aes(geometry = geometry), color = "black", size = .5)
From this point I guess it's easy to find the areas not within XX meters of any of the points plotted.
If you want to find area across the underlying polygons you can simply use the following (blue areas are within 50 km of any of the points plotted while red areas don't):
# calculate union shape for all buffers
points_buff_union <- points %>%
filter(NAME_1 != "Corse") %>%
dplyr::select(-geometry) %>%
st_as_sf() %>%
summarise()
# generate bounding box
mask_union <- union %>% as_tibble() %>%
mutate(bbox = st_as_sfc(st_bbox(c(xmin = -5.5, xmax = 9, ymax = 51.5, ymin = 42), crs = st_crs(4326)))) %>%
st_as_sf()
# compute difference between bounding box and union polygon to
# use as mask in the final layer
diff <- st_difference(mask_union$bbox, mask_union$geometry)
# plot content
polygon %>%
ggplot() +
geom_sf(fill = "red3") +
geom_sf(data = points_buff_union, aes(geometry = buffer), fill = "lightblue") +
geom_sf(data = points, aes(geometry = geometry), color = "black", size = .5) +
geom_sf(fill = NA) +
geom_sf(data = diff, fill = "white")
Of course you can plot the individual layers computed with sf also using tmap:
library(tidyverse)
library(sf)
library(geodata)
library(tmap)
# example polygons of France
EofEMSOAs <- gadm(country = "FRA", level = 1, path = tempdir()) %>%
st_as_sf() %>%
filter(NAME_1 != "Corse")
# get 100 sample points within union shape of polygons
set.seed(42)
union <- st_union(EofEMSOAs)
PointDataPlot <- st_sample(x = union, size = 100, type = "random") %>%
as.data.frame() %>%
# calculate around each point a buffer zone of 50km
mutate(buffer = st_buffer(geometry, dist = 50000)) %>%
select(-geometry) %>%
st_as_sf()
# generate bounding box
mask_union <- union %>% as_tibble() %>%
mutate(bbox = st_as_sfc(st_bbox(c(xmin = -5.5, xmax = 9, ymax = 51.5, ymin = 42), crs = st_crs(4326)))) %>%
st_as_sf()
# compute difference between bounding box and union polygon to
# use as mask in the final layer
diff <- st_difference(mask_union$bbox, mask_union$geometry)
# Build map
OutputMap <-
# plot only shapes filled red
tm_shape(EofEMSOAs) +
tm_fill(col = "red") +
# plot only buffer zones of each point in green
tm_shape(PointDataPlot)+
tm_fill(col = "forestgreen") +
# add mask
tm_shape(diff) +
tm_fill(col = "white") +
# plot borders of shape
tm_shape(EofEMSOAs) +
tm_borders(col = "white",
lwd = 1,
lty = "solid") +
# add custom legend
tm_add_legend(type = "symbol",
labels = c("Restricted", "Public"),
col = c("red", "forestgreen"),
title = "Access type",
size = 1.5,
shape = 21)
UPDATE using UK data
#Call necessary packages
library(tidyverse)
library (readxl)
library(maptools)
library(classInt)
library(RColorBrewer)
library(sf)
library(tmap)
library(scales)
library(tmaptools)
library(geodata)
# Read in boundary polygon data
EofEMSOAs <- st_read("MSOA_EngWal_Dec_2011_Generalised_ClippedEW_0/Middle_Layer_Super_Output_Areas_December_2011_Generalised_Clipped_Boundaries_in_England_and_Wales.shp")%>%
st_as_sf(crs = 4326) %>%
st_make_valid() %>%
# use only a subset of the data
st_crop(c(xmin = 550000, ymin =320000, xmax = 600000, ymax = 360000))
# Generate point data
PointData <- read.table(textConnection("ID Latitude Longitude
A 52.9742585 0.5526301
B 52.972643 0.8495693
C 52.972643 0.8495693
D 51.46133804 0.36403501"), header=TRUE)
# Geocode the point list
PointDataPlotted = st_as_sf(PointData, coords = c('Longitude','Latitude'), crs = 4326)
# Remove geometry
PointDataPlotted2 <- PointDataPlotted %>%
as.data.frame() %>%
mutate(buffer = st_buffer(geometry, dist = 5000)) %>%
select(-geometry) %>%
st_as_sf(crs = 4326)
# Create union shape of polygons
union <- st_union(EofEMSOAs)
# generate bounding box
mask_union <- union %>% as_tibble() %>%
mutate(bbox = st_as_sfc(st_bbox(geometry), crs = 4326)) %>%
st_as_sf()
# compute difference between bounding box and union polygon to
# use as mask in the final layer
diff <- st_difference(mask_union$bbox, mask_union$geometry)
# Build map
OutputMap <-
# plot only shapes filled red
tm_shape(EofEMSOAs) +
tm_fill(col = "red") +
# plot only buffer zones of each point in green
tm_shape(PointDataPlotted2)+
tm_fill(col = "forestgreen") +
# add mask
tm_shape(diff) +
tm_fill(col = "white") +
# plot borders of shape
tm_shape(EofEMSOAs) +
tm_borders(col = "white",
lwd = 1,
lty = "solid") +
# add custom legend
tm_add_legend(type = "symbol",
labels = c("Restricted", "Public"),
col = c("red", "forestgreen"),
title = "Access type",
size = 1.5,
shape = 21)
I'm looking to create a masking polygon for multiple polygons.
It's easy enough for a single polygon:
How to apply a polygon mask layer in ggplot
but much trickier for multiple:
https://www.stat.auckland.ac.nz/~paul/Reports/GraphicsEngine/definitions/definitions.html
I feel like I'm fairly close but I need a method of drawing a line between a point for the closest polygon, i.e. I'd like to try and connect nearest islands with a line.
While also connecting those polygons to an outer polygon box but only with a single line:
library(tidyverse)
library(sf)
library(albersusa)
usa <- usa_sf()
HI <- st_coordinates(usa %>%
filter(name %in% c("Hawaii"))) %>%
as.data.frame() %>%
select(X, Y)
rec_box <-
data.frame(
X = c(-108,-108,-101,-101,-108),
Y = c(24, 28, 28, 24, 24)
)
mask <- rbind(HI, rec_box)
eg <- st_as_sf(data.frame(mask), coords = c("X", "Y"))
poly <- st_convex_hull(eg)
ggplot() +
geom_sf(data = poly) +
geom_density2d_filled(data = HI, aes(x = X, y = Y)) +
geom_polygon(data = mask,
aes(x = X, y = Y),
color = "black",
fill = "white")
Edit:
For only a mask around the islands:
library(tidyverse)
library(sf)
#> Linking to GEOS 3.8.0, GDAL 3.0.4, PROJ 6.3.1
library(albersusa)
#library(concaveman)
#library(nngeo)
usa <- usa_sf()
# keep only the geometry from Hawaii (not the data)
HI <- usa %>%
filter(name %in% c("Hawaii")) %>%
st_cast('POLYGON') %>%
st_geometry() %>%
st_as_sf()
# HI as dataframe as your example
HI2 <- st_coordinates(usa %>%
filter(name %in% c("Hawaii"))) %>%
as.data.frame() %>%
select(X, Y)
# you may need a larger box. This uses sf:st_bbox to get exact
# rectangle of the polygons. adjust accordingly
hi_box <- st_bbox(HI) %>% st_as_sfc() %>% st_as_sf()
# find the difference betwee HI & hi_box
hi_mask <- st_difference(hi_box, st_union(HI))
ggplot() +
geom_density_2d_filled(data = HI2, aes(x = X, y = Y)) +
geom_sf(data = hi_mask, fill = 'black')
Created on 2021-04-04 by the reprex package (v0.3.0)
If you're happy with the HI mask created above, you can connect it to your defined bounding box using a single line with nngeo::st_connect().
This should find the shortest connecting line between the two. If you prefer the connecting line to be at a specific point (southwest corner in your example above), supply it as an sf object to the st_connect() function instead of the entire box.
library(tidyverse)
library(sf)
#> Linking to GEOS 3.8.0, GDAL 3.0.4, PROJ 6.3.1
library(albersusa)
library(concaveman)
library(nngeo)
usa <- usa_sf()
# Hawaii, cast to POLYGON rather than the original MULTIPOLYGON
HI <- (usa %>%
filter(name %in% c("Hawaii"))) %>%
st_cast('POLYGON')
connected_HI <- concaveman(HI)
# rec box as an sf object with same crs as HI
rec_box <-
data.frame(X = c(-108, -108, -101, -101, -108),
Y = c(24, 28, 28, 24, 24)) %>%
st_as_sf(coords = c('X', 'Y'
)) %>%
st_set_crs(st_crs(HI))
# connecting HI mask you made to your rec_box
connected_to_rec_box <- nngeo::st_connect(st_zm(connected_HI), rec_box)
ggplot() +
geom_sf(data = connected_HI, fill = 'turquoise', alpha = .4) +
geom_sf(data = connected_to_rec_box, color = 'red')
Created on 2021-04-04 by the reprex package (v0.3.0)
I need to create a map of country(Thailand) based on shapes files (preferably colored)and to add the codes of the provinces (from 10 to 96,77 codes) and the corresponding coefficient from h.сsv(also 77 values) file on the map.
I am trying to show my two codes(maybe,one of them will be better for map):
1st:
library(raster)
library(rasterVis)
library(rgdal)
library(rgeos)
library(dismo)
library(sp)
library(maptools)
library(maps)
library(mapdata)
library(XML)
library(foreign)
library(latticeExtra)
library(shapefiles)
library(RColorBrewer)
library(GISTools)
#library(SDMTools)
library(dplyr)
library(tidyr)
library(tidyverse)
library(lubridate)
## preparing shapefiles
thailand_district <- shapefile("C:/usa/archive/TH_Province2012.shp")
thailand_district
crs(thailand_district)
names(thailand_district)
thailand_district_lonlat<- spTransform(thailand_district, CRS("+proj=longlat +datum=WGS84"))
crs(thailand_district_lonlat)
thailand_district_lonlat_s<-gSimplify(thailand_district_lonlat, tol=0.02, topologyPreserve=TRUE)
district_id<-thailand_district_lonlat$A_CODE
province_id<-thailand_district_lonlat$P_CODE
thailand_prov <- shapefile("C:/usa/archive/TH_Province2012.shp")
thailand_prov
crs(thailand_prov)
thailand_prov_lonlat<- spTransform(thailand_prov, CRS("+proj=longlat +datum=WGS84"))
crs(thailand_prov_lonlat)
thailand_prov_lonlat_s<-gSimplify(thailand_prov_lonlat, tol=0.02, topologyPreserve=TRUE)
## preparing centroids
thailand_district_centroids <- getSpPPolygonsLabptSlots(thailand_district_lonlat)
head(thailand_district_centroids)
district_centroids<- data.frame(province_id,district_id, thailand_district_centroids[,1],thailand_district_centroids[,2])
district_centroids<-read.csv("data.scrub.district.csv")
names(district_centroids) <- c("province_id","district_id","longitude", "latitude")
ex<-district_centroids
coordinates(ex)<- cbind("longitude", "latitude")
plot(ex)
thailand_province_centroids <- getSpPPolygonsLabptSlots(thailand_prov_lonlat)
head(thailand_province_centroids)
## read cases
scrub1<-read_csv("C:/usa/archive/scrub_2003-07_180319.csv")
names(scrub1)
scrub1<-dplyr::select(scrub1,Address, The.day.began.to.get.sick..M.D.Y.)
scrub1 <- dplyr::rename(scrub1,date=The.day.began.to.get.sick..M.D.Y.)
scrub1 <-na.omit(scrub1)
scrub2<-read_csv("C:/usa/archive/scrub_2008-11_180319.csv")
scrub2<-dplyr::select(scrub2,Address, The.day.began.to.get.sick..M.D.Y.)
scrub2 <- dplyr::rename(scrub2,date=The.day.began.to.get.sick..M.D.Y.)
scrub3<-read_csv("C:/usa/archive/scrub_2012-18_180319.csv")
scrub3<-dplyr::select(scrub3,Address, The.day.began.to.get.sick..M.D.Y.)
scrub3 <- dplyr::rename(scrub3,date=The.day.began.to.get.sick..M.D.Y.)
scrub<-dplyr::union(scrub1, scrub2)
scrub<-dplyr::union(scrub, scrub3)
scrub$district_id<-(tamboon_id=substr(scrub$Address, 1,4))
scrub <- dplyr::rename(scrub,village_id=Address)
scrub<-tidyr::drop_na(scrub,village_id)
scrub_district <- dplyr::select(scrub,district_id)
# preparation
scrub$date1 <- as.Date(scrub$date,
format = "%d/%m/%Y")
scrub$year<-lubridate::year(scrub$date1)
scrub$YearMonth<-format(scrub$date1, "%Y-%m")
scrubYear<-scrub %>%
drop_na() %>%
group_by(year) %>%
summarise(scrubcases= n())
scrub$district_id<-as.factor(scrub$district_id)
is.factor(scrub$district_id)
scrubDistrict<-scrub %>%
drop_na() %>%
group_by(district_id) %>%
summarise(scrubcases= n())
district_centroids
district_centroids2<-district_centroids %>%
unite("district_id", province_id,district_id2)
district_centroids2$district_id<-gsub("_", "",district_centroids2$district_id )
scrubdistict_longlat<-dplyr::left_join(district_centroids2,scrubDistrict,
by="district_id")
write_csv(scrubdistict_longlat,"data.scrub.district.csv")
scrubClean<-read_csv("data.scrub.district.csv")
mydata<-dplyr::filter(scrubClean, scrubcases > 0)
ex2<-mydata
coordinates(ex2)<-c("longitude","latitude")
bubble(ex2,"scrubcases")
# map
library(tmap)
library(tmaptools)
proj4string(ex2) <- proj4string(thailand_district_lonlat)
tmaptools::palette_explorer()
# thailand
tm1<-tm_shape(thailand_prov_lonlat_s) +
tm_fill(NA) + tm_borders("black")+
tm_borders("black")+
tm_compass(type = "8star", position = c("right", "top"),size = 2)+
tm_scale_bar(breaks = c(0, 100, 100), size = 0.5, position = c("right", "bottom"))+
tm_style( "beaver")
tm1
tm2<-tm_shape(thailand_district_lonlat_s)+
tm_polygons()+
tm_shape(ex2) +
tm_bubbles("scrubcases",col = "lightblue",scale = 2,
border.col = "black", border.alpha = .5,
contrast=1,
title.size="cases / district")
tm2
library(dplyr)
library(tidyr)
library(tmap)
data(World)
names(World)
mygideon<-read_csv("data.gideon.iso.final.csv") %>%
group_by(iso_a3) %>%
summarise(total.outbreaks=n())
world2<-dplyr::left_join(World,mygideon2,by="iso_a3")
tm_shape(world2) +
tm_polygons("total.outbreaks",
style = "fixed",
breaks = c(1,50,100,250,500,750, 1000, 1500, 2500),
palette="Oranges",
title = "Total outbreaks (1940-2018)", contrast = 1.2,
border.col = "gray30", id = "name", n=6,
legend.hist = TRUE,alpha = 1)+
tm_layout(legend.outside = TRUE)
**Error in data.frame(province_id, district_id, thailand_district_centroids[, :
arguments imply differing number of rows : 0, 77.use coordinates method**
2n code.
library(raster)
library(rasterVis)
library(rgdal)
library(rgeos)
library(dismo)
library(sp)
library(maptools)
library(maps)
library(mapdata)
library(XML)
library(foreign)
library(latticeExtra)
library(shapefiles)
library(RColorBrewer)
library(GISTools)
#library(SDMTools)
library(dplyr)
library(tidyr)
library(tidyverse)
library(rgeos) # to fortify without needing gpclib
library(ggplot2)
library(scales) # for formatting ggplot scales with commas
thamap <- readOGR("C:/usa/archive/TH_Province2012.shp")
thamap
crs(thamap)
thamap_lonlat<- spTransform(thamap, CRS("+proj=longlat +datum=WGS84"))
crs(thamap_lonlat)
thamap_lonlat_s<-gSimplify(thamap_lonlat, tol=0.02, topologyPreserve=TRUE)
thamap.fort <- fortify(thamap)
idList <-thamap#data$PROV_CODE
centroids.df <- as.data.frame(coordinates(thamap))
names(centroids.df) <- c("Longitude", "Latitude")
info <- read.csv("h.csv")
pop.df <- data.frame(idList,info,centroids.df)
ggplot(pop.df, aes(map_id = idList)) + #"id" is col in your df, not in the map object
geom_map(aes(fill = info), colour= "grey", map = thamap.fort) +
expand_limits(x = thamap.fort$long, y = thamap.fort$lat) +
scale_fill_gradient(high = "red", low = "white", guide = "colorbar", labels = comma) +
geom_text(aes(label = id, x = Longitude, y = Latitude)) + #add labels at centroids
coord_equal(xlim = c(-90,-30), ylim = c(-60, 20)) +
labs(x = "Longitude", y = "Latitude", title = "map Thailand") +
theme_bw()
Don't know how to automatically pick scale for object of type function. Defaulting to continuous.
Aesthetics must be valid data columns. Problematic aesthetic(s): label = id.
Did you mistype the name of a data column or forget to add after_stat()?
I would really appreciate it if you could help me to fix my codes a little to create the map.
Could you tell me please also,how is it possible to add the data(77 values) from csv file on the map near the codes of provinces?
Thank you very much for your help
Here's a solution using tmap. The shapefile containing the borders of Thailand (country and provinces) is available from https://data.humdata.org/dataset/thailand-administrative-boundaries. The province codes (10-96) are also included in the dataset in character format and can easily be extracted.
library(tmap)
library(sf)
library(tidyverse)
provinces <- st_read(dsn = "tha_adm_rtsd_itos_20190221_SHP_PART_1/tha_admbnda_adm1_rtsd_20190221.shp") %>%
as.tibble() %>%
separate(ADM1_PCODE, into = c("pcode_text", "pcode_num"), sep = "(?<=[A-Za-z])(?=[0-9])") %>%
select(geometry, pcode_num) %>%
st_as_sf()
tm_shape(provinces) +
tm_fill(col = "MAP_COLORS") +
tm_text("pcode_num", size = .5) +
tm_borders(lwd = .7, col = "black")
What I have:
points in the arctic and antarctic
raster data from various geophysical entities in arctic and antarctic
What I want:
A map in stereographic or any other polar projection with background map or coastlines, cropped to the extent of the points. In other words: A map like above with base map of my own choice.
What I did so far:
I loaded all the data (including land surface data from naturalearthdata; see MWE), projected them into stereographic and plotted that. The result including the polygon data looks then like this:
My MWE:
library(raster)
library(sf)
library(ggplot2)
library(rgdal)
# file load ---------------------------------------------------------------
# sea ice raster data
if (!file.exists("seaiceraster.tif")) {
url = "https://seaice.uni-bremen.de/data/smos/tif/20100514_hvnorth_rfi_l1c.tif"
download.file(url, destfile = 'seaiceraster.tif')
}
si.raster = raster::raster('seaiceraster.tif')
# land surface shapefile
if (!file.exists("110m-admin-0-countries")) {
url_land = "https://www.naturalearthdata.com/http//www.naturalearthdata.com/download/10m/physical/ne_10m_land.zip"
download.file(url_land, destfile = "110m-admin-0-countries")
unzip("110m-admin-0-countries")
}
world_shp = rgdal::readOGR("ne_10m_land.shp")
# points
p.data = structure(
list(
Lat = c(
73.0114126168676,70.325555278764,77.467797903163,
58.6423827457304,66.3616310851294,59.2097857474643,
75.3135274436283,60.1983078512275,72.6614399747201,
61.1566678672946,73.0822309615673,55.7759666826898,
75.1651656433833,69.0130753414173,62.3288262448589
),
Lon = c(
-59.9175490701543,-80.1900239630732,-40.4609968914928,
-61.0914448815381,-60.0703668488408,-21.027205418284,
-100.200463810276,-74.861777073788,-55.1093773178206,
-29.4108649230234,-64.5878251008461,-36.5343322019187,
-31.647365623387,-67.466355105829,-64.1162329769077
)
),
row.names = c(
1911L, 592L,2110L,3552L,3426L,1524L,635L,4668L,
3945L,2848L,3609L,36L,4262L,3967L,2725L
),
class = "data.frame"
)
p = sf::st_as_sf(p.data, coords = c("Lon", "Lat"),
crs = "+init=epsg:4326")
# project -----------------------------------------------------------------
polar.crs = CRS("+init=epsg:3995")
si.raster.proj = projectRaster(si.raster, crs = polar.crs)
world_shp.proj = sp::spTransform(world_shp, polar.crs)
p.proj = sf::st_transform(p, polar.crs)
# preparation -------------------------------------------------------------
AG = ggplot2::fortify(world_shp.proj)
# make raster to data.frame
si.raster.df = si.raster.proj %>%
raster::crop(., p.proj) %>%
raster::rasterToPoints(., spatial = TRUE) %>%
as.data.frame(.)
colnames(si.raster.df) = c("val", "x", "y")
# plot --------------------------------------------------------------------
ggplot() +
# geom_polygon(data = AG, aes(long, lat, group = group)) + # un-comment to see
geom_raster(data = si.raster.df, aes(x = x, y = y, fill = val)) +
geom_sf(data = p.proj, color = "green", size = 3)
I've changed the workflow in your example a bit to add the stars package for the sea ice data, but I think it should get you what you're looking for. You'll need to adjust the crop size to expand it a little, as the points p are right on the edge of the plotted area. st_buffer might help with that.
I used the crs from the seaicebuffer.tif file for all of the objects.
The .tif file has a crs that I'm not able to easily transform on my computer. It seems to be able to use meters as a lengthunit and might be a polar stereographic (variant B) projection. The points & world data don't seem to have a problem transforming to it though, which is why I've used it throughout.
library(raster)
library(sf)
library(ggplot2)
library(rgdal)
library(stars)
si <- stars::read_stars('seaiceraster.tif')
world_sf = rgdal::readOGR("ne_10m_land.shp") %>%
st_as_sf() %>%
st_transform(st_crs(si))
# p <- ... same as example and then:
p <- st_transform(p, st_crs(si))
# get a bounding box for the points to crop si & world.
p_bbox <- st_bbox(p) %>%
st_as_sfc() %>%
st_as_sf() %>%
st_buffer(100000)
# crop si & world_sf to an area around the points (p)
world_cropped <- st_crop(world_sf, p_bbox)
si_cropped <- st_crop(si, p_bbox)
#Plot
ggplot() +
geom_sf(data = world_cropped,
color = 'black',
fill = 'NA',
size = .2) +
geom_stars(data = si_cropped) +
geom_sf(data = p, color = 'red') +
scale_fill_continuous(na.value = 0)
Ugly hack for the southern .tif that stars reads as factors:
si <- stars::read_stars('20150324_hvsouth_rfi_l1c.tif', NA_value = 0 )
si$"20150324_hvsouth_rfi_l1c.tif" <- as.numeric(si$"20150324_hvsouth_rfi_l1c.tif")
ggplot() + geom_stars(data = si)
How can I define the boundaries of a country, so rivers outside the country won't appear on the map? The image link below will clarify what I mean:
US Rivers
library(tidyverse) # ggplot2, dplyr, tidyr, readr, purrr, tibble
library(magrittr) # pipes
library(rnaturalearth) # Rivers
library(urbnmapr)
states <- urbnmapr::states
states <- fortify(states)
rivers10 <- ne_download(scale = "medium", type = 'rivers_lake_centerlines', category = 'physical') #, returnclass = "sf"
rivers10 <- fortify(rivers10)
rivers10 <- rivers10 %>%
filter(long >= min(states$long)) %>%
filter(long <= max(states$long)) %>%
filter(lat >= min(states$lat)) %>%
filter(lat <= max(states$lat))
ggplot() +
geom_polygon(data = urbnmapr::states, mapping = aes(x = long, y = lat, group = group),
fill = "#CDCDCD", color = "#25221E") +
coord_map(projection = "albers", lat0 = 39, lat1 = 45) +
geom_path(data = rivers10,
aes(long, lat, group = group), size = 1, color = '#000077') +
theme_minimal()
This is easier if you get the data as spatial objects. Then you can manipulate them to intersect the rivers with the US boundary.
library(tidyverse) # ggplot2, dplyr, tidyr, readr, purrr, tibble
library(rnaturalearth) # Rivers
library(sf)
library(urbnmapr)
states = get_urbn_map('states', sf=TRUE)
rivers10 <- ne_download(scale = "medium", type = 'rivers_lake_centerlines',
category = 'physical', returnclass = "sf")
# Outline of the US
us = st_union(states)
# Transform rivers to the same projection as states and clip to US
rivers10 <- rivers10 %>%
st_transform(st_crs(states)) %>%
st_intersection(us)
ggplot() +
geom_sf(data=states, fill = "#CDCDCD", color = "#25221E") +
geom_sf(data=rivers10, color='#000077') +
theme_minimal()
Created on 2019-12-26 by the reprex package (v0.3.0)