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")
Related
I'm looking to crop the density plot to only land while keeping to sf.
Here's a simple example problem:
library(tidyverse)
library(sf)
library(albersusa)
library(ggthemes)
library(jsonlite)
dat <-
fromJSON(
"https://services1.arcgis.com/Hp6G80Pky0om7QvQ/arcgis/rest/services/Fortune_500_Corporate_Headquarters/FeatureServer/0/query?where=1%3D1&outFields=LATITUDE,LONGITUDE,NAME,PROFIT&outSR=4326&f=json"
)
dat <- as.data.frame(dat$features$attributes)
top_50 <- dat %>%
arrange(desc(PROFIT)) %>%
head(50)
ggplot() +
geom_sf(data = usa_sf()) +
geom_density_2d_filled(aes(x = LONGITUDE, y = LATITUDE),
data = top_50,
alpha = .5) +
xlim(-125,-66.5) +
ylim(20, 50) +
theme_map() +
theme(legend.position = "none")
Not sure if I'm getting close to a solution but here's some of the code I've been trying:
test <- (MASS::kde2d(
top_50$LONGITUDE, top_50$LATITUDE,
lims = c(-125,-66.5, 20, 50)
))
ggpoly2sf <- function(poly, coords = c("long", "lat"),
id = "group", region = "region", crs = 4326) {
sf::st_as_sf(poly, coords = coords, crs = crs) %>%
group_by(!! as.name(id), !! as.name(region)) %>%
summarize(do_union=FALSE) %>%
sf::st_as_sf("POLYGON") %>%
ungroup() %>%
group_by(!! as.name(region)) %>%
summarize(do_union = TRUE) %>%
ungroup()
}
v <- contourLines(test)
vv <- v
for (i in seq_along(v)) vv[[i]]$group <- i
vv <- do.call(rbind, lapply(vv, as.data.frame))
dsi_sf <- ggpoly2sf(vv, coords = c("x", "y"), region = "level") %>% st_as_sf()
usa <- usa_sf()
dsi_i_sf <- st_intersection(usa$geometry, dsi_sf)
ggplot() +
geom_sf(data=usa) +
geom_sf(data=dsi_i_sf,color="red") +
geom_density2d_filled(aes(x = LONGITUDE, y = LATITUDE),
data = top_50,alpha=.4) +
xlim(-125,-66.5) +
ylim(20, 50) +
theme(legend.position = "none")
Create a rectangle of the same plot dimensions:
rec_box <- data.frame(x=c(-125,-125,-66.5,-66.5,-125), y=c(20,50,50,20,20))
Create an outline of the US and extract only the lat/lon points into a dataframe:
outline <- map("usa", plot=FALSE)
outline <- data.frame(x=outline$x,y=outline$y)
Bind the two together to create a polygon with a hole in the middle:
mask <- rbind(rec_box,outline)
Add a geom_polygon() to plot the mask data and color appropriately:
geom_polygon(data=mask,
aes(x=x,y=y),color="white",fill="white")
Everything combined:
library(tidyverse)
library(sf)
library(albersusa)
library(ggthemes)
library(jsonlite)
dat <-
fromJSON(
"https://services1.arcgis.com/Hp6G80Pky0om7QvQ/arcgis/rest/services/Fortune_500_Corporate_Headquarters/FeatureServer/0/query?where=1%3D1&outFields=LATITUDE,LONGITUDE,NAME,PROFIT&outSR=4326&f=json"
)
dat <- as.data.frame(dat$features$attributes)
top_50 <- dat %>%
arrange(desc(PROFIT)) %>%
head(50)
usa <- usa_sf()
outline <- map("usa", plot=FALSE)
outline <- data.frame(x=outline$x,y=outline$y)
rec_box <- data.frame(x=c(-125,-125,-66.5,-66.5,-125), y=c(20,50,50,20,20))
mask <- rbind(rec_box,outline)
ggplot() +
geom_sf(data = usa_sf()) +
geom_density_2d_filled(aes(x = LONGITUDE, y = LATITUDE),
data = top_50,
alpha = .5) +
xlim(-125,-66.5) +
ylim(20, 50) +
geom_polygon(data=mask,
aes(x=x,y=y),color="white",fill="white") +
theme_map() +
theme(legend.position = "none")
Really a thing of beauty.
For a mask layer over the US with AK & HI inset:
library(tidyverse)
library(sf)
library(albersusa)
library(ggthemes)
library(jsonlite)
library(spatstat)
dat <-
fromJSON(
"https://services1.arcgis.com/Hp6G80Pky0om7QvQ/arcgis/rest/services/Fortune_500_Corporate_Headquarters/FeatureServer/0/query?where=1%3D1&outFields=LATITUDE,LONGITUDE,NAME,PROFIT&outSR=4326&f=json"
)
dat <- as.data.frame(dat$features$attributes)
top_50 <- dat %>%
arrange(desc(PROFIT)) %>%
head(50)
usa <- usa_sf()
top50sf <- st_as_sf(top_50, coords = c("LONGITUDE", "LATITUDE")) %>%
st_set_crs(4326) %>%
st_transform(st_crs(usa))
# usa polygons combined
usa_for_mask <- usa_sf() %>%
st_geometry() %>%
st_cast('POLYGON') %>%
st_union()
# bounding box of us & inset AK + HI,
# expand as needed
us_bbox <- st_bbox(usa_for_mask) %>%
st_as_sfc() %>%
st_as_sf()
us_mask <- st_difference(us_bbox, usa_for_mask)
ggplot() +
geom_sf(data = usa) +
geom_density_2d_filled(aes(x = LONGITUDE, y = LATITUDE),
data = top_50,
alpha = .5) +
geom_sf(data = us_mask, fill = 'white') +
xlim(-125,-66.5) +
ylim(20, 50) +
theme_map() +
theme(legend.position = "none")
Created on 2021-04-05 by the reprex package (v1.0.0)
You can expand the bounding box to get rid of the purple border around the plot.
This does what you're asking for, but almost certainly isn't spatially accurate. It can get a point across to a general audience, but don't make any big decisions based on it.
More accurate spatial interpolation methods can be found here:
https://rspatial.org/raster/analysis/4-interpolation.html
https://mgimond.github.io/Spatial/interpolation-in-r.html
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)
I have spatial coordinates in a data frame where each row (Longitude, Latitude) corresponds to the occurrence of an event I am following. I tried to map these data but instead of using points, I want to create a grid with cells of a resolution of 5 nautical miles (~ 0.083333) and count the number of occurrences of the event is each cell and plot it.
This is the code I came to write with the help of some resources. But it doesn't look the way I expected it to be. Can you figure out what's I'm doing wrong? I attached the raw positions and the resulting map I get.
Here is the link to the data.
re_pi = read.csv(file = "~/Desktop/Events.csv")
gridx <- seq(from=-19,to=-10,by=0.083333)
gridy <- seq(from=20,to=29,by=0.083333)
xcell <- unlist(lapply(re_pi$LON,function(x) min(which(gridx>x))))
ycell <- unlist(lapply(re_pi$LAT,function(y) min(which(gridy>y))))
re_pi$cell <- (length(gridx) - 1) * ycell + xcell
rr = re_pi %>%
group_by(cell)%>%
summarise(Lat = mean(LAT),Lon = mean(LON),Freq = length(cell))
my_theme <- theme_bw() + theme(panel.ontop=TRUE, panel.background=element_blank())
my_cols <- scale_color_distiller(palette='Spectral')
my_fill <- scale_fill_distiller(palette='Spectral')
ggplot(rr, aes(y=Lat, x=Lon, fill=Effort)) + geom_tile(width=1.2, height=1.2) +
borders('world', xlim=range(rr$Lon), ylim=range(rr$Lat), colour='black') + my_theme + my_fill +
coord_quickmap(xlim=range(rr$Lon), ylim=range(rr$Lat))
Nice dataset, assume these are fishing vessel VMS data. Here may be one way to achieve your objective, heavily reliant on the tidyverse and by-passing raster and shapes.
library(tidyverse)
library(mapdata) # higher resolution maps
# poor man's gridding function
grade <- function (x, dx) {
if (dx > 1)
warning("Not tested for grids larger than one")
brks <- seq(floor(min(x)), ceiling(max(x)), dx)
ints <- findInterval(x, brks, all.inside = TRUE)
x <- (brks[ints] + brks[ints + 1])/2
return(x)
}
d <-
read_csv("https://raw.githubusercontent.com/abenmhamed/data/main/Events.csv") %>%
janitor::clean_names() %>%
# make a grid 0.01 x 0.01 longitude / latitude
mutate(lon = grade(lon, 0.01),
lat = grade(lat, 0.01)) %>%
group_by(lon, lat) %>%
count() %>%
# not much happening south of 21 and north of 26
filter(between(lat, 21, 26.25))
d %>%
ggplot() +
theme_bw() +
geom_tile(aes(lon, lat, fill = n)) +
scale_fill_viridis_c(option = "B", direction = -1) +
# only data within the data-bounds
borders(database = "worldHires",
xlim = range(d$lon), ylim = range(d$lat),
fill = "grey") +
labs(x = NULL, y = NULL, fill = "Effort") +
# limit plot
coord_quickmap(xlim = range(d$lon), ylim = range(d$lat)) +
# legends within plot
theme(legend.position = c(0.77, 0.26))
Here is my attempt using the sf package. First I imported your data and converted it to an sf object. Then, I created another sf object which includes the grids. I used the raster package and the sf package in order to create the grids. Once I had the two sf object, I counted how many data points exist in each grid and added the results as a new column in foo. Finally, I drew a graphic.
library(tidyverse)
library(sf)
library(raster)
library(viridis)
# Import the data and convert it to an sf object
mydata <- read_csv("https://raw.githubusercontent.com/abenmhamed/data/main/Events.csv") %>%
st_as_sf(coords = c("LON", "LAT"),
crs = 4326, agr = "constant")
# Create an sf object for the grid
gridx <- seq(from = -19,to = -10, by = 0.083333)
gridy <- seq(from = 20,to = 29, by = 0.083333)
foo <- raster(xmn = -19, xmx = -10,
ymn = 20, ymx = 29,
nrows = length(gridx),
ncols = length(gridy)) %>%
rasterToPolygons() %>%
st_as_sf(crs = 4326) %>%
mutate(group = 1:(length(gridx)*length(gridy))) %>%
st_cast("MULTIPOLYGON")
# Now count how many data points exist in each grid
mutate(foo,
count = lengths(st_intersects(x = foo, y = mydata))) -> foo
# Draw a graphic
ggplot() +
geom_sf(data = foo, aes(fill = count)) +
scale_fill_viridis(option = "D") -> g
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)
I want to dissolve a polygon so I get only a lines for the outline of the whole region instead of it being broken up by county.
install.packages (c("tidyverse","mapdata","maps","stringr","viridis"))
library(tidyverse)
library(mapdata)
library(maps)
library(stringr)
library(viridis)
california <- map_data("state", region="california")
california1 <- ggplot() +
geom_polygon(data = california,
aes(x = long, y = lat, group = group),
color="black", fill="NA") +
coord_quickmap()
#california county lines
uscounties <-map_data("county")
ca_county <- uscounties %>% filter(region == "california")
central<- ca_county %>%
filter(subregion %in% c("alpline", "kings", "tulare", "fresno", "inyo", "kern", "madera"))
ca2 <- california1 +
theme_void() +
geom_polygon(data = central,
aes(x = long, y = lat, group = group),
fill = "white", color = "black") +
geom_polygon(color = "black", fill = NA) +
annotate("text", x = -119, y = 46.5, label="Central", colour="black")
ca2
Thanks in advance for the help!
I've answered a similar question before. Reworked it slightly for your use case, with explanations in annotated code below:
library(tidyverse)
library(maps)
# get map (as map object)
county_map <- map("county", regions = "california",
fill = T, plot = FALSE)
# convert to SpatialPolygonsDataFrame object (using maptools & sp packages)
county_map_match <- data.frame(name = county_map$names) %>%
separate(name, c("region", "subregion"), sep = ",", remove = FALSE) %>%
mutate(central = subregion %in% c("alpline", "kings", "tulare",
"fresno", "inyo", "kern", "madera")) %>%
column_to_rownames("name")
county_map <- maptools::map2SpatialPolygons(county_map, ID = county_map$names)
county_map <- sp::SpatialPolygonsDataFrame(county_map, county_map_match)
rm(county_map_match)
# remove any invalidity (using rgeos package) before dissolving
rgeos::gIsValid(county_map) # check
county_map <- rgeos::gBuffer(county_map, byid = TRUE, width = 0)
rgeos::gIsValid(county_map) # check again (invalidities removed)
# dissolve by whether each polygon is part of central area
county_map <- maptools::unionSpatialPolygons(county_map, IDs = county_map$central)
county_map <- fortify(county_map)
county_map <- county_map %>% filter(group == "TRUE.1")
# plot all the central counties as one polygon
ggplot() +
geom_polygon(data = county_map,
aes(x = long, y = lat, group = group),
fill = "white", colour = "black") +
coord_map()