219 lines
8.6 KiB
Markdown
219 lines
8.6 KiB
Markdown
|
+++
|
||
|
title = "Streetmaps"
|
||
|
date = 2021-01-09T00:00:00+01:00
|
||
|
lastmod = 2021-01-11T23:48:01+01:00
|
||
|
draft = false
|
||
|
subtitle = "Cómo hacer bonitos callejeros"
|
||
|
math = true
|
||
|
diagram = true
|
||
|
publication_types = ""
|
||
|
publication = "MPVD"
|
||
|
featured = true
|
||
|
projects = ["periodismodatos"]
|
||
|
abstract_short = "Cómo hacer bonitos callejeros con R"
|
||
|
authors = ["adolfo_anton"]
|
||
|
abstract = "Cómo hacer bonitos callejeros con R y ggplot2"
|
||
|
|
||
|
[image]
|
||
|
caption = "[Orion aveugle cherchant le soleil](https://commons.wikimedia.org/wiki/File:Orion_aveugle_cherchant_le_soleil.jpg), Nicolas Poussin / Public domain"
|
||
|
focal_point = "BottomLeft"
|
||
|
placement = 3
|
||
|
preview_only = false
|
||
|
+++
|
||
|
|
||
|
El título original es mucho más feo ya que incluye al final "y PowerPoint": "Create a streetmap of your favorite city with ggplot2 and powerpoint". En este caso vamos a intentar no usar esa herramienta por no ser software libre.
|
||
|
|
||
|
El propósito del autor era crear mapas/callejeros como el de este [cartel](https://www.mapiful.com/de/editor/#!/location/?startFrom=332036):
|
||
|
|
||
|
Para este tutorial se utilizan dos paquetes de R: [osmdata](https://github.com/ropensci/osmdata) y [ggplot2](https://ggplot2.tidyverse.org/). Con `osmdata` se extraen las calles de [OpenStreetMap](https://www.openstreetmap.org/), una base de datos libre con licencia abierta. Ni siquiera requiere de una clave para trabajar con su API. Para crear las visualizaciones y trabajar con los datos se utiliza `tidyverse`.
|
||
|
|
||
|
El autor no había trabajado mucho con `ggplot2` y se inspiró especialmente en [Dominic Royé](https://dominicroye.github.io/en/2018/accessing-openstreetmap-data-with-r/) y su detallado trabajo de datos OpenStreetMap con R.
|
||
|
|
||
|
Se puede empezar por la ciudad en la que estás, en la que vives, en la que naciste o una que te gusta. En su caso empezó por Freiburg, en el sur de Alemania. Para elegir la ciudad tan solo hay que ajustar la longitud y latitud de los puntos de inicio.
|
||
|
|
||
|
Lo primero es instalar las librerías necesarias, `tidyverse` y `osmdata`:
|
||
|
|
||
|
```R
|
||
|
library(tidyverse)
|
||
|
library(osmdata)
|
||
|
```
|
||
|
|
||
|
Antes de trabajar con R hay que entender cómo almacena [OpenStreetMap](https://wiki.openstreetmap.org/wiki/Map%5FFeatures) los datos de las calles. OpenStreetMap describe las cosas físicas como "características" o "rasgos", del inglés "features". Estas características se almacenan como pares de clave-valor. Por ejemplo hay [highways](https://wiki.openstreetmap.org/wiki/Map%5FFeatures#Highway) que son vías principales que pueden conectar tanto la ciudad en sí como la ciudad con otras.
|
||
|
|
||
|
Para obtener todas las etiquetas de una característica espacial vía osmdata introducimos la siguiente función:
|
||
|
|
||
|
```R
|
||
|
available_tags("highway")
|
||
|
```
|
||
|
|
||
|
De la misma manera, se pueden obtener todas las características con la función `available_features()`:
|
||
|
|
||
|
```R
|
||
|
available_features()
|
||
|
```
|
||
|
|
||
|
Para obtener las coordenadas de la ciudad que elijamos se puede usar la función `getbb()`. Por ejemplo, con Murcia:
|
||
|
|
||
|
```R
|
||
|
getbb("Murcia Spain")
|
||
|
```
|
||
|
|
||
|
Esto nos da las [coordenadas](https://en.wikipedia.org/wiki/Geographic%5Fcoordinate%5Fsystem) de la ciudad. el valor de la `x` da la longitud mientras que la `y` da la altitud.
|
||
|
|
||
|
Ahora queremos exportar las carreteras del sistema de coordenadas. Para ello primero pasamos la salida de la función `getbb` a la función [opq](https://rdrr.io/cran/osmdata/man/opq.html).
|
||
|
|
||
|
A continuación pasamos esta salida a la función [add\_osm\_feature](https://github.com/ropensci/osmdata). La función tiene dos argumentos. Con la clave especificamos la clave de la característica; con el valor especificamos la etiqueta de la característica.
|
||
|
|
||
|
En este caso primero extraemos las principales calles de la ciudad y las pasamos a la función [osmdata\_sf](https://www.rdocumentation.org/packages/osmdata/versions/0.1.1/topics/osmdata%5Fsf) para insertarlo luego en `ggplot2`.
|
||
|
|
||
|
```R
|
||
|
streets <- getbb("Murcia Spain")%>%
|
||
|
opq()%>%
|
||
|
add_osm_feature(key = "highway",
|
||
|
value = c("motorway", "primary",
|
||
|
"secondary", "tertiary")) %>%
|
||
|
osmdata_sf()
|
||
|
streets
|
||
|
```
|
||
|
|
||
|
Los datos los hemos almacenado en la variable `streets`. Este objeto tiene diferentes objetos hijxs. `osm_lines` son especialmente interesantes para el mapa las líneas de `osm_lines` mientras que los puntos hablan de lugares.
|
||
|
|
||
|
Ahora obtenemos también las calles más pequeñas y el río de Murcia, el Segura, de la misma base de datos:
|
||
|
|
||
|
```R
|
||
|
small_streets <- getbb("Murcia Spain")%>%
|
||
|
opq()%>%
|
||
|
add_osm_feature(key = "highway",
|
||
|
value = c("residential", "living_street",
|
||
|
"unclassified",
|
||
|
"service", "footway")) %>%
|
||
|
osmdata_sf()
|
||
|
|
||
|
river <- getbb("Murcia Spain")%>%
|
||
|
opq()%>%
|
||
|
add_osm_feature(key = "waterway", value = "river") %>%
|
||
|
osmdata_sf()
|
||
|
```
|
||
|
|
||
|
Y creamos nuestro primer mapa:
|
||
|
|
||
|
```R
|
||
|
ggplot() +
|
||
|
geom_sf(data = streets$osm_lines,
|
||
|
inherit.aes = FALSE,
|
||
|
color = "black",
|
||
|
size = .4,
|
||
|
alpha = .8) +
|
||
|
coord_sf(xlim = c(-1.38, -0.85),
|
||
|
ylim = c(37.71, 38.11),
|
||
|
expand = FALSE)
|
||
|
```
|
||
|
|
||
|
Primero se añade la geometría [geom\_sf](https://ggplot2.tidyverse.org/reference/ggsf.html) a la función `ggplot`. Para los datos añadimos las calles almacenadas en la variable `streets$osm_lines`. Se puede determinar la anchura de las calles con `size`. Para que las calles no estén completamente negras se ha creado una pequeña transparencia con el nivel `alpha`.
|
||
|
|
||
|
Con la función `coord_sf` se puede determinar el eje de las X y de las Y exactamente. Es mejor jugar con los valores hasta que has definido los límites.
|
||
|
|
||
|
Con `expand = FALSE` nos aseguramos de que se muestren las coordenadas correctamente.
|
||
|
|
||
|
Ahora se añaden calles pequeñas y ríos:
|
||
|
|
||
|
```R
|
||
|
ggplot() +
|
||
|
geom_sf(data = streets$osm_lines,
|
||
|
inherit.aes = FALSE,
|
||
|
color = "black",
|
||
|
size = .4,
|
||
|
alpha = .8) +
|
||
|
geom_sf(data = small_streets$osm_lines,
|
||
|
inherit.aes = FALSE,
|
||
|
color = "black",
|
||
|
size = .4,
|
||
|
alpha = .6) +
|
||
|
geom_sf(data = river$osm_lines,
|
||
|
inherit.aes = FALSE,
|
||
|
color = "black",
|
||
|
size = .2,
|
||
|
alpha = .5) +
|
||
|
coord_sf(xlim = c(-1.38, -0.85),
|
||
|
ylim = c(37.71, 38.11),
|
||
|
expand = FALSE)
|
||
|
```
|
||
|
|
||
|
En vez de negro se pueden resaltar las calles en color:
|
||
|
|
||
|
```R
|
||
|
ggplot() +
|
||
|
geom_sf(data = streets$osm_lines,
|
||
|
inherit.aes = FALSE,
|
||
|
color = "steelblue",
|
||
|
size = .4,
|
||
|
alpha = .8) +
|
||
|
geom_sf(data = small_streets$osm_lines,
|
||
|
inherit.aes = FALSE,
|
||
|
color = "black",
|
||
|
size = .4,
|
||
|
alpha = .6) +
|
||
|
geom_sf(data = river$osm_lines,
|
||
|
inherit.aes = FALSE,
|
||
|
color = "black",
|
||
|
size = .2,
|
||
|
alpha = .5) +
|
||
|
coord_sf(xlim = c(-1.38, -0.85),
|
||
|
ylim = c(37.71, 38.11),
|
||
|
expand = FALSE)
|
||
|
```
|
||
|
|
||
|
There's one more thing that's disturbing, though. The x- and y-axis. To remove them we can add the function theme\_void():
|
||
|
|
||
|
ggplot() +
|
||
|
geom\_sf(data = streets$osm\_lines,
|
||
|
inherit.aes = FALSE,
|
||
|
color = "steelblue",
|
||
|
size = .4,
|
||
|
alpha = .8) +
|
||
|
geom\_sf(data = small\_streets$osm\_lines,
|
||
|
inherit.aes = FALSE,
|
||
|
color = "black",
|
||
|
size = .4,
|
||
|
alpha = .6) +
|
||
|
geom\_sf(data = river$osm\_lines,
|
||
|
inherit.aes = FALSE,
|
||
|
color = "black",
|
||
|
size = .2,
|
||
|
alpha = .5) +
|
||
|
coord\_sf(xlim = c(7.77, 7.92),
|
||
|
ylim = c(47.94, 48.06),
|
||
|
expand = FALSE) +
|
||
|
theme\_void()
|
||
|
Next, we can adjust the colors of the visualization. I want to create not only a white streetmap, but also one with a dark background:
|
||
|
|
||
|
ggplot() +
|
||
|
geom\_sf(data = streets$osm\_lines,
|
||
|
inherit.aes = FALSE,
|
||
|
color = "#7fc0ff",
|
||
|
size = .4,
|
||
|
alpha = .8) +
|
||
|
geom\_sf(data = small\_streets$osm\_lines,
|
||
|
inherit.aes = FALSE,
|
||
|
color = "#ffbe7f",
|
||
|
size = .2,
|
||
|
alpha = .6) +
|
||
|
geom\_sf(data = river$osm\_lines,
|
||
|
inherit.aes = FALSE,
|
||
|
color = "#ffbe7f",
|
||
|
size = .2,
|
||
|
alpha = .5) +
|
||
|
coord\_sf(xlim = c(7.77, 7.92),
|
||
|
ylim = c(47.94, 48.06),
|
||
|
expand = FALSE) +
|
||
|
theme\_void() +
|
||
|
theme(
|
||
|
plot.background = element\_rect(fill = "#282828")
|
||
|
)
|
||
|
Now that we've created both visualizations, we can make a poster out of it. To do so I first exported the visualizations as a png file. Make sure that you execute the function right after you have created your streetmap.
|
||
|
|
||
|
ggsave("map.png", width = 6, height = 6)
|
||
|
Next, I created a Powerpoint file and resized it. Then I imported the png file and enlarged it. You might also need to crop the png first. As text I used the font Lato. I recommend that you search the internet for photos of streetmaps and use these examples as a guide. There are already countless beautiful designs that you can recreate relatively easily in Powerpoint.
|
||
|
|
||
|
The examples from this tutorial can be found here. Feel free to share your own streetmaps on Twitter, I'm curious what you create.
|