Maps are a very informative way of displaying data. In this example we are going to visualize population size by postcoded areas to a map with Leaflet
, geofi
and pxweb
R-packages. With following code map of population statistics can be plotted reproducible. Visit links below to get more information of the packages and pxweb
API:
- geofi R Package https://github.com/rOpenGov/geofi
- Leaflet for R https://rstudio.github.io/leaflet/
- PXWeb API interface for R https://cran.r-project.org/web/packages/pxweb/vignettes/pxweb.html
- PXWeb API HELP https://www.stat.fi/static/media/uploads/org_en/avoindata/px-web_api-help.pdf
Load necessary libraries
First you need to have packages available in your R instance. Package geofi
can be installed from Github repo with following command
remotes::install_github("ropengov/geofi")
Other packages you can find from CRAN. Install them with install.packages()
function if not already.
# Load necessary packages
library(geofi)
##
## geofi R package: tools for open GIS data for Finland.
## Part of rOpenGov <ropengov.github.io>.
library(ggplot2)
library(leaflet)
library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following object is masked from '.env':
##
## n
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(janitor)
##
## Attaching package: 'janitor'
## The following objects are masked from 'package:stats':
##
## chisq.test, fisher.test
library(pxweb)
## pxweb: R tools for PX-WEB API.
## Copyright (C) 2014-2018 Mans Magnusson, Leo Lahti et al.
## https://github.com/ropengov/pxweb
library(tidyr)
Download and prepare datasets
For this example we are going to plot population size by postcoded areas of city of Kuopio. First download spatial data with geofi
package.
## Get post code map data
municipalities <- get_municipalities(year = 2019) %>% filter(nimi == "Kuopio")
## Requesting response from: http://geo.stat.fi/geoserver/wfs?service=WFS&version=1.0.0&request=getFeature&typename=tilastointialueet%3Akunta4500k_2019
## Warning: Coercing CRS to epsg:3067 (ETRS89 / TM35FIN)
## Data is licensed under: Attribution 4.0 International (CC BY 4.0)
zipcodes <- get_zipcodes(year = 2019) %>% filter(kunta == municipalities$kunta)
## Requesting response from: http://geo.stat.fi/geoserver/wfs?service=WFS&version=1.0.0&request=getFeature&typename=postialue%3Apno_2019
## Warning: Coercing CRS to epsg:3067 (ETRS89 / TM35FIN)
## Data is licensed under: Attribution 4.0 International (CC BY 4.0)
After this, let’s download population statistics data with pxweb
-package and shape data format a bit
## Get stat.fi data
pxweb_query_list <- list("Postinumeroalue" = zipcodes$posti_alue,
"Tiedot" = c("He_vakiy",
"He_kika"))
px_data <- pxweb_get(url = "http://pxnet2.stat.fi/PXWeb/api/v1/fi/Postinumeroalueittainen_avoin_tieto/2019/paavo_1_he_2019.px",
query = pxweb_query_list)
# wrangle to data frame
tk_data <- as.data.frame(px_data, column.name.type = "text", variable.value.type = "text")
## Warning in pxweb_as_data_frame.pxweb_data(x, row.names = row.names, optional =
## optional, : NAs introduced by coercion
tk_data <- tk_data %>%
rename(avointieto = `Paavo - Postinumeroalueittainen avoin tieto 2019`) %>%
mutate(posti_alue = substr(Postinumeroalue, 1,5)) %>%
spread(Tiedot, avointieto) %>%
janitor::clean_names() %>%
as_tibble()
Join spatial and population datasets together
## Join datasets and transform to leaflet data
dat <- left_join(zipcodes, tk_data)
## Joining, by = "posti_alue"
zipcodes_lonlat <- sf::st_transform(x = dat, crs = "+proj=longlat +datum=WGS84")
Plotting a leaflet map
Plot interactive map with leaflet
package
## Plot leaflet map
leaflet(zipcodes_lonlat, height=720, width=720) %>%
# Add the OSM, CartoDB and Esri tiles
addTiles(group = "OSM") %>%
addProviderTiles("CartoDB", group = "CartoDB") %>%
addProviderTiles("Esri", group = "Esri") %>%
# Use addLayersControl to allow users to toggle between basemaps
addLayersControl(baseGroups = c("OSM", "CartoDB", "Esri")) %>%
addPolygons(color = "coral",
weight = 1,
smoothFactor = .5,
opacity = .9,
fillColor = ~colorBin(palette = "plasma", asukkaat_yhteensa_2017_he)(asukkaat_yhteensa_2017_he),
fillOpacity = 0.5,
label = ~paste0(nimi, " (", posti_alue ,") ", asukkaat_yhteensa_2017_he, " asukasta, keski-ikä ",asukkaiden_keski_ika_2017_he," vuotta"),
highlightOptions = highlightOptions(color = "white",
weight = 2,
bringToFront = TRUE)) %>%
setView(lat = 62.89238, lng = 27.67703, zoom=8)
With small changes in code, you can plot different municipalities or even whole countrys population to a map. For more examples, check GitHub project https://github.com/janikmiet/example_maps