Spacial data for region mapping - r

I have some data in the UK and I need to introduce a map of all 9 regions of England. I tried using library(maps) but the plots I get do not have any regional information and I just end up with the whole of the United Kingdom.
Ideally i am looking for a result like this
https://upload.wikimedia.org/wikipedia/commons/thumb/b/b4/English_regions_2009.svg/370px-English_regions_2009.svg.png
(I cant actually attach pictures due to the lack of reputation points,apologies!)
My data has a column for regions with character values:
EastMid
EastEng
London
NorthEast
NorthWest
SouthEast
SouthWest
WestMid
Yorkshire
I would then go on to map by color regions with different attributes
How would I go on about this?

First, as Andrew wrote you need to find and download shapefiles with necessary regions. Such split as you need is usually called historical regions or standard statistical regions. You might want to check this site: http://www.natureonthemap.naturalengland.org.uk/
Second, you read shapefile and merge with referendum data. Make sure that region names at the referendum file are exactly the same as in geospatial file (I use file downloaded from the site mentioned above, if you download another shapefile the names probably will be different):
library(rgdal)
library(tmap)
geoEN = readOGR(".", "maghistengland")
In this case region names are stored in NAME (in another shapefile attribute name can be different). You can check what information consists of geospatial file by:
ogrInfo(".", "maghistengland")
For the purpose of the example I am creating fake figures of voting results.
votes = as.data.frame(
cbind(
c("EAST MIDLANDS",
"EAST OF ENGLAND",
"LONDON",
"NORTH EAST",
"NORTH WEST",
"SOUTH EAST",
"WEST MIDLANDS",
"YORKSHIRE AND THE HUMBER",
"SOUTH WEST"),
c(60, 65, 55, 50, 45, 40, 35, 30, 30),
c(40, 35, 45, 50, 55, 60, 65, 70, 70)
), stringsAsFactors = FALSE)
names(votes) = c("Regions", "Yes", "No")
votes$Yes = as.numeric(votes$Yes)
votes$No = as.numeric(votes$No)
votes$Result = colnames(votes)[max.col(votes[,2:3])+1]
Now we can merge both files:
mapEN = append_data(geoEN, votes, key.shp = "NAME", key.data = "Regions")
Third, create necessary charts. Here are three examples. You can play with number of groups (n = 2, 3, 4..), colors etc.
tm_shape(mapEN) +
tm_fill("Yes", title = "This is a title", palette = "Blues", n=4) +
tm_borders(alpha=.5)
tm_shape(mapEN) +
tm_fill("No", title = "This is a title", palette = "Reds", n=5) +
tm_borders(alpha=.5)
tm_shape(mapEN) +
tm_fill("Result", palette = c("Red", "Blue")) +
tm_borders(alpha=.5)

Related

How to add the state names to the Australia map?

I have written the following code:
library(ozmaps)
oz(states = TRUE, coast = TRUE,
ylim = NULL, add = FALSE, ar = 1, eps = 0.25)
That generates:
I wonder how to add the names of the states on the map? If the whole process can be done by "map" package, it is fine as well.
Thanks.
I'm not familiar with package ozmaps. I could not find data for the state names and latitude and longitude values for state centroids within the package.
A quick internet search produced some representative state data from https://www.distancelatlong.com/distancecalculator/country/australia/
You can adjust this data or find a better source, so this should be a start.
library(tibble)
library(ggplot2)
library(ozmaps)
ggplot(ozmap_states)+
geom_sf()+
geom_text(data = oz_states, aes(long, lat, label = state))+
theme_void()
data
oz_states <- tribble(
~state, ~lat, ~long,
"Australian Capital Territory", -35.3546004, 149.2113468,
"New South Wales", -33.42004148, 151.3000048,
"Northern Territory", -13.81617348, 131.816698,
"Queensland", -26.67998777, 153.0500272,
"South Australia", -34.28293455, 140.6000378,
"Tasmania", -40.83292234, 145.1166613,
"Victoria", -37.73119953, 142.0234135,
"Western Australia", -33.58287392, 120.0333345
)
Created on 2021-03-29 by the reprex package (v1.0.0)

R - Print specific country names in a map using rworldmap

I am creating a heatmap using the map of Europe in rworldmap package in R (since I don't know how to do this with ggmap or ggplot2).
I need to plot the country names of the countries that are present in my dataframe only, not all european countries. How can I do this?
My code:
library(RColorBrewer)
#getting colours
colourPalette <- brewer.pal(5,'RdPu')
library(rworldmap)
europe <- data.frame(
"country" = c("Greece",
"France",
"Spain",
"Italy",
"UK",
"Finland","Norway","Sweden",
"Germany",
"Romania"),
"x" = c(2.5, 3, 2.2, 1.8,2.32, 1.99, 2.01, 2.34, 1.88, 2.45))
matched <- joinCountryData2Map(europe, joinCode="NAME", nameJoinColumn="country")
mapParams <- mapCountryData(matched,
nameColumnToPlot="x",
mapTitle="my Titley",
addLegend=FALSE,
mapRegion="Europe"
,colourPalette=colourPalette,
oceanCol="#404040", missingCountryCol="#A0A0A0")
#adding legend
do.call(addMapLegend
,c(mapParams
,legendLabels="all"
,legendWidth=0.5
,legendIntervals="data"
,legendMar = 2))
labelCountries()
Using labelCountries() prints all country names and it's not readable.
Thanks
With a little bit help of this previously answer:
# get the coordinates for each country
country_coord<-data.frame(coordinates(matched),stringsAsFactors=F)
# label the countries
country = c("Greece",
"France",
"Spain",
"Italy",
"UK",
"Finland","Norway","Sweden",
"Germany",
"Romania")
#filter your wanted countrys
country_coord = country_coord[country,]
#insert your labels in plot
text(x=country_coord$X1,y=country_coord$X2,labels=row.names(country_coord))
you can add the country labels with text but you must extract the coordinates before from your matched coordinates.
Output:
You might play a bit with col = "color" in text, since some country can barely been read. Or maybe change the color scale in your map

Geographical county level heat map

I frequently need to create geographical heat maps in R. Currently, I have been doing it in a licensed version of Tableau in my office computer which does a superb job. But I need to learn how to do it when I'm out of office. The data is sometimes confidential, so I cannot use Tableau public over the internet. I looked but could not find any solution that produces the result I need.
The data consists of names of districts in the state of Jharkhand, India along with child population in age group 6 to 14 in thousands. In Tableau, I merely have to set the DISTNAME column to "Geographical Role" at "County" level and it pulls the map of the state along with district boundaries from the internet (OpenStreetMap) and produces a heat map like this which is the result I expect from R, if possible:
The data is:
geo_data <- structure(list(DISTNAME = c("BOKARO", "CHATRA", "DEOGHAR", "DHANBAD",
"DUMKA", "GARHWA", "GIRIDIH", "GODDA", "GUMLA", "HAZARIBAGH",
"JAMTARA", "KHUNTI", "KODARMA", "LATEHAR", "LOHARDAGA", "PAKUR",
"PALAMU", "PASHCHIMI SINGHBHUM", "PURBI SINGHBHUM", "RAMGARH",
"RANCHI", "SAHIBGANJ", "SARAIKELA-KHARSAWAN", "SIMDEGA"), POP = c(521.5,
196.5, 323.8, 445.5, 123, 373.9, 357.6, 248.2, 212.4, 686.7,
626.7, 383.6, 391.9, 141, 436.1, 454.6, 301.3, 325.5, 193.7,
238.3, 208.7, 587.4, 130.1, 268)), .Names = c("DISTNAME", "POP"
), row.names = c(NA, 24L), class = "data.frame")
And looks like:
DISTNAME POP
1 BOKARO 521.5
2 CHATRA 196.5
3 DEOGHAR 323.8
4 DHANBAD 445.5
5 DUMKA 123.0
6 GARHWA 373.9
7 GIRIDIH 357.6
8 GODDA 248.2
9 GUMLA 212.4
10 HAZARIBAGH 686.7
11 JAMTARA 626.7
12 KHUNTI 383.6
13 KODARMA 391.9
14 LATEHAR 141.0
15 LOHARDAGA 436.1
16 PAKUR 454.6
17 PALAMU 301.3
18 PASHCHIMI SINGHBHUM 325.5
19 PURBI SINGHBHUM 193.7
20 RAMGARH 238.3
21 RANCHI 208.7
22 SAHIBGANJ 587.4
23 SARAIKELA-KHARSAWAN 130.1
24 SIMDEGA 268.0
You'll need SHP file, which can be found using getData(). Full working code:
library(tidyverse)
library(broom)
library(rgdal)
Your geo data
geo_data <- structure(list(DISTNAME = c("BOKARO", "CHATRA", "DEOGHAR", "DHANBAD", "DUMKA", "GARHWA", "GIRIDIH", "GODDA", "GUMLA", "HAZARIBAGH", "JAMTARA", "KHUNTI", "KODARMA", "LATEHAR", "LOHARDAGA", "PAKUR", "PALAMU", "PASHCHIMI SINGHBHUM", "PURBI SINGHBHUM", "RAMGARH", "RANCHI", "SAHIBGANJ", "SARAIKELA-KHARSAWAN", "SIMDEGA"),
POP = c(521.5, 196.5, 323.8, 445.5, 123, 373.9, 357.6, 248.2, 212.4, 686.7, 626.7, 383.6, 391.9, 141, 436.1, 454.6, 301.3, 325.5, 193.7, 238.3, 208.7, 587.4, 130.1, 268)),
.Names = c("DISTNAME", "POP"),
row.names = c(NA, 24L),
class = "data.frame")
get the map
library(raster)
IN2 <- getData('GADM', country='IND', level=2)
IN2 <- spTransform(IN2, CRS("+init=epsg:4326"))
IN2_map <- tidy(IN2, region = "NAME_2")
id in geo_data to lower
geo_data$DISTNAME <- tolower(geo_data$DISTNAME)
IN2_map %>%
mutate(id = tolower(id)) %>%
left_join(geo_data, by = c("id" = "DISTNAME")) %>%
ggplot() +
geom_polygon(aes(long, lat, group=group, fill = POP), color = "black")
In the solution below I've used map shapefiles downloaded from: http://projects.datameet.org/maps/districts/
Edit: Later I also tried Jharkhand map extracted from http://gadm.org/country which shows slight differences in district boundaries. It matches better with other political maps of the state available on the internet.
Here's my solution:
library(tmap)
library(tmaptools)
geo_data <- data.frame(
DISTNAME = c("BOKARO", "CHATRA", "DEOGHAR", "DHANBAD", "DUMKA", "GARHWA", "GIRIDIH", "GODDA", "GUMLA", "HAZARIBAGH", "JAMTARA", "KHUNTI", "KODARMA", "LATEHAR", "LOHARDAGA", "PAKUR", "PALAMU", "PASHCHIMI SINGHBHUM", "PURBI SINGHBHUM", "RAMGARH", "RANCHI", "SAHIBGANJ", "SARAIKELA-KHARSAWAN", "SIMDEGA"),
POP = c(521.5, 196.5, 323.8, 445.5, 123, 373.9, 357.6, 248.2, 212.4, 686.7, 626.7, 383.6, 391.9, 141, 436.1, 454.6, 301.3, 325.5, 193.7, 238.3, 208.7, 587.4, 130.1, 268))
# the path to shape file
shp_file <- "H:/Mapping/maps-master/Districts/Census_2011/2011_Dist.shp"
india <- read_shape(shp_file, as.sf = TRUE, stringsAsFactors = FALSE)
india$DISTRICT <- toupper(india$DISTRICT)
jharkhand <- india[india$ST_NM =="Jharkhand", ]
jharkhand_pop <- merge(x = jharkhand,
y = geo_data,
by.x = "DISTRICT",
by.y = "DISTNAME")
#tmap_mode(mode = "plot") # static
tmap_mode(mode = "view") # interactive
qtm(jharkhand_pop, fill = "POP",
text = "DISTRICT",
text.size=.9)
The static map (plot mode) is very good but the interactive map (view mode) is super awesome. It gives the option to pull additional map information from three different sources from the internet.
A big thanks to the creators of tmap and tmaptools packages. This method is far superior to many comparatively longer and awkward solutions that can be found on the internet.
If we want more customization:
tm_shape(jharkhand_pop) +
tm_polygons() +
tm_shape(jharkhand_pop) +
tm_borders() +
tm_fill("POP",
palette = get_brewer_pal("YlOrRd", n = 20),
n = 20,
legend.show = F,
style = "order") + # "cont" or "order" for continuous variable
tm_text("DISTRICT", size = .7, ymod = .1) +
tm_shape(jharkhand_pop) +
tm_text("POP", size = .7, ymod = -.2)
we get the following in plot mode:

Map of India in R with Different Values of Five Indicators for Every State of India

I want to generate a map of India in R. I have five indicators with different values of every state. I want to plot bubbles with five different colors, and their size should represent their intensity in every state. For example:
State A B C D E
Kerala - 39, 5, 34, 29, 11
Bihar - 6, 54, 13, 63, 81
Assam - 55, 498, 89, 15, 48,
Chandigarh - 66, 11, 44, 33, 71
I have gone through some links related to my problem:
[1] http://www.r-bloggers.com/nrega-and-indian-maps-in-r/
[2] An R package for India?
But these links could not serve my purpose. Any help in this direction would be greatly appreciated.
I have also tried
library(mapproj)
map(database= "world", regions = "India", exact=T, col="grey80", fill=TRUE, projection="gilbert", orientation= c(90,0,90))
lat <- c(23.30, 28.38)
lon <- c(80, 77.12) # Lon and Lat for two cities Bhopal and Delhi
coord <- mapproject(lon, lat, proj="gilbert", orientation=c(90, 0, 90))
points(coord, pch=20, cex=1.2, col="red")
In nut shell problems are:
(1) It does not give me plot at district level. Not even boundries of states.
(2) How to create bubbles or dots of my data in this plot, if I have only name of locations and corresponding value to plot?
(3) can this be done in easily in library(RgoogleMaps) or library(ggplot2)? (Just a guess, I do not know much about these packages)
As #lawyeR states, a choropleth (or thematic) map is more commonly used to represent variables on a map. This would require you to produce one map per variable. Let me take you through an example:
require("rgdal") # needed to load shapefiles
# obtain India administrative shapefiles and unzip
download.file("http://biogeo.ucdavis.edu/data/diva/adm/IND_adm.zip",
destfile = "IND_adm.zip")
unzip("IND_adm.zip", overwrite = TRUE)
# load shapefiles
india <- readOGR(dsn = "shapes/", "IND_adm1")
# check they've loaded correctly with a plot
plot(india)
# all fine. Let's plot an example variable using ggplot2
require("ggplot2")
require("rgeos") # for fortify() with SpatialPolygonsDataFrame types
india#data$test <- sample(65000:200000000, size = nrow(india#data),
replace = TRUE)
# breaks the shapefile down to points for compatibility with ggplot2
indiaF <- fortify(india, region = "ID_1")
indiaF <- merge(indiaF, india, by.x = "id", by.y = "ID_1")
# plots the polygon and fills them with the value of 'test'
ggplot() +
geom_polygon(data = indiaF, aes(x = long, y = lat, group = group,
fill = test)) +
coord_equal()
Finally, I notice you asked the same question on GIS SE. This is considered bad practice and is generally frowned upon, so I've flagged that question to be closed as a duplicate of this. As a general rule of thumb try not to create duplicates.
Good luck!
Once you have the shapefile for India, you need to create a choropleth. That will take the shapefule map and color each State in India on a gradient that reflects your data. You may want to create a panel of five plots, each one showing India and its states colored according to one of your five variables.
For others who can push this answer farthr, here is the dput of the data frame, after a bit of cleaning.
dput(df)
structure(list(State = c("Kerala", "Bihar", "Assam", "Chandigarh"
), A = c("39", "6", "55", "66"), B = c("5", "54", "498", "11"
), C = c("34", "13", "89", "44"), D = c("29", "63", "15", "33"
), E = c("11", "81", "48", "71")), .Names = c("State", "A", "B",
"C", "D", "E"), row.names = c("Kerala", "Bihar", "Assam", "Chandigarh"
), class = "data.frame")

How to create a world map in R with specific countries filled in?

I would like to use R to generate a very basic world map with a specific set of countries filled with a red colour to indicate that they are malaria endemic countries.
I have a list of these countries in a data frame but am struggling to overlay them on a world map.
I have tried using the wrld_simpl object and also the joinCountryData2Map method in the rworldmap package.
I would comment on this answer to prevent addition of a possibly redundant question but I do not have enough reputation at the moment, apologies for this.
https://stackoverflow.com/a/9102797/1470099
I am having difficulty understanding the arguments given to the plot() command - I wondered if there was just an easy way to tell R to plot all of the country NAMEs in my list on the wrld_simpl map instead of using grepl() etc. etc.
plot(wrld_simpl,
col = c(gray(.80), "red")[grepl("^U", wrld_simpl#data$NAME) + 1])
Using the rworldmap package, you could use the following:
library(rworldmap)
theCountries <- c("DEU", "COD", "BFA")
# These are the ISO3 names of the countries you'd like to plot in red
malDF <- data.frame(country = c("DEU", "COD", "BFA"),
malaria = c(1, 1, 1))
# malDF is a data.frame with the ISO3 country names plus a variable to
# merge to the map data
malMap <- joinCountryData2Map(malDF, joinCode = "ISO3",
nameJoinColumn = "country")
# This will join your malDF data.frame to the country map data
mapCountryData(malMap, nameColumnToPlot="malaria", catMethod = "categorical",
missingCountryCol = gray(.8))
# And this will plot it, with the trick that the color palette's first
# color is red
EDIT: Add other colors and include picture
## Create multiple color codes, with Burkina Faso in its own group
malDF <- data.frame(country = c("DEU", "COD", "BFA"),
malaria = c(1, 1, 2))
## Re-merge
malMap <- joinCountryData2Map(malDF, joinCode = "ISO3",
nameJoinColumn = "country")
## Specify the colourPalette argument
mapCountryData(malMap, nameColumnToPlot="malaria", catMethod = "categorical",
missingCountryCol = gray(.8), colourPalette = c("red", "blue"))
Try using googleVis package and use gvisGeoMap Functions
e.g.
G1 <- gvisGeoMap(Exports,locationvar='Country',numvar='Profit',options=list(dataMode='regions'))
plot(G1)
library(maptools)
data(wrld_simpl)
myCountries = wrld_simpl#data$NAME %in% c("Australia", "United Kingdom", "Germany", "United States", "Sweden", "Netherlands", "New Zealand")
plot(wrld_simpl, col = c(gray(.80), "red")[myCountries+1])

Resources