Creating Beautiful Artistic Maps with R and OpenStreetMap Data
Written on
Chapter 1: Introduction to Artistic Mapping
When you envision a map, the initial thought often revolves around its role as a tool for navigation. However, maps can transcend their informational purpose to become works of art. By customizing their visual features, we can transform standard maps into captivating visuals without sacrificing the essential location details.
In the past, creating a map required extensive surveys and manual constructions, which was a time-consuming process. Fortunately, with the advent of open data sources like OpenStreetMap (OSM) and programming capabilities, we can now design our own maps tailored to our aesthetic preferences. Additionally, these artistic maps can be sold in marketplaces, providing a potential revenue stream.
In this guide, I will outline the steps necessary to create an artistic map using R. Let’s dive in!
Implementation Steps
Loading Required Libraries
To build our artistic map, we need to load several libraries:
- osmdata: For downloading and loading OpenStreetMap data.
- tidyverse: To facilitate data processing and visualization.
- sf: For converting OSM data into the sf format.
If you haven’t installed these libraries yet, you can do so with the following commands:
install.packages('osmdata')
install.packages('sf')
install.packages('sysfonts')
In case of a timeout error, increase the timeout limit with:
options(timeout=600)
Once the libraries are installed, load them using the following commands:
library(osmdata)
library(tidyverse)
library(sf)
Retrieving Spatial Data
As mentioned, we will utilize OpenStreetMap data to extract spatial information, such as roads, buildings, and bodies of water. We will use the osmdata library for this purpose. Below is the code to retrieve spatial data for streets and waterways in Amsterdam:
streets <- getbb('Amsterdam Netherlands') %>%
opq() %>%
add_osm_feature(key='highway', value=c('motorway', 'primary', 'secondary', 'tertiary')) %>%
osmdata_sf()
small_streets <- getbb('Amsterdam Netherlands') %>%
opq() %>%
add_osm_feature(key='highway', value=c('residential', 'living_street', 'service', 'footway')) %>%
osmdata_sf()
rivers <- getbb('Amsterdam Netherlands') %>%
opq() %>%
add_osm_feature(key='natural', value=c('water')) %>%
osmdata_sf()
In the code above, we define three variables—streets, small_streets, and rivers—to store different types of spatial data. This segregation will make it easier to customize their visuals.
Building the Map
Now, let’s create our artistic map using the ggplot2 library. First, visualize the basic map with the following code:
ggplot() +
geom_sf(data=streets$osm_lines, inherit.aes = FALSE, color = '#58b9c7', size = .5, alpha = .6) +
geom_sf(data=small_streets$osm_lines, inherit.aes = FALSE, color = '#239dc1', size = .2, alpha = .6) +
geom_sf(data=rivers$osm_polygons, inherit.aes = FALSE, fill='#f8cc0a', size = .2)
At this stage, the map appears, but it may need refinement. To enhance the view, we can crop the coordinates with the coord_sf function:
ggplot() +
geom_sf(data=streets$osm_lines, inherit.aes = FALSE, color = '#58b9c7', size = .5, alpha = .6) +
geom_sf(data=small_streets$osm_lines, inherit.aes = FALSE, color = '#239dc1', size = .2, alpha = .6) +
geom_sf(data=rivers$osm_polygons, inherit.aes = FALSE, fill='#f8cc0a', size = .2) +
coord_sf(ylim=c(52.35, 52.40), xlim=c(4.83, 4.97), expand=FALSE)
Now the map looks better! We can further enhance its appearance by adjusting visual elements through the theme function:
ggplot() +
geom_sf(data=streets$osm_lines, inherit.aes = FALSE, color = '#58b9c7', size = .5, alpha = .6) +
geom_sf(data=small_streets$osm_lines, inherit.aes = FALSE, color = '#239dc1', size = .2, alpha = .6) +
geom_sf(data=rivers$osm_polygons, inherit.aes = FALSE, fill='#f8cc0a', size = .2) +
coord_sf(ylim=c(52.35, 52.40), xlim=c(4.83, 4.97), expand=FALSE) +
theme(
plot.background = element_blank(),
panel.background = element_rect(color='#08435f', fill='#08435f', size = 20),
panel.grid = element_blank(),
axis.ticks = element_blank(),
axis.text = element_blank()
)
Adding Titles and Saving the Plot
To include a title and frame around the plot, use the labs function, along with additional tweaks in the theme function:
ggplot() +
geom_sf(data=streets$osm_lines, inherit.aes = FALSE, color = '#58b9c7', size = .5, alpha = .6) +
geom_sf(data=small_streets$osm_lines, inherit.aes = FALSE, color = '#239dc1', size = .2, alpha = .6) +
geom_sf(data=rivers$osm_polygons, inherit.aes = FALSE, fill='#f8cc0a', size = .2) +
coord_sf(ylim=c(52.35, 52.40), xlim=c(4.83, 4.97), expand=FALSE) +
labs(title = 'Amsterdam') +
theme(
plot.background = element_rect(fill="#f8cc0a", color='#f8cc0a'),
plot.margin = unit(c(0.3, 0.4, 0.5, 0.4), 'cm'),
panel.background = element_rect(color='#08435f', fill='#08435f', size = 20),
panel.grid = element_blank(),
axis.ticks = element_blank(),
axis.text = element_blank(),
plot.title = element_text(size=18, face='bold', hjust=.5, color='#08435f')
)
Finally, to save your artistic map, use the ggsave function specifying your desired dimensions:
ggsave('artistic_map.png', width=1920, height=1080, units='px')
Final Thoughts
Congratulations! You have successfully learned how to create an artistic map using R. I hope this guide enhances your understanding of data visualization, particularly in the realm of geospatial data.
If you found this article valuable, consider following me on Medium for more insights related to data science and machine learning. Thank you for reading!