Ocultar código
library(glue)
library(showtext)
library(ggtext)
library(sf)
library(magick)
library(tidyverse)
Sitio en construcción
Víctor Gauto
17 de febrero de 2024
Animación del avance de las torres de telecomunicaciones en Argentina, entr 2009 y 2024, para redes GSM, UMTS y LTE.
Colores.
Fuentes: Ubuntu y JetBrains Mono.
fuente <- glue(
"Datos: <span style='color:{c2}; font-size: 8px'>**OpenCelliD Project** is
licensed under a Creative<br>Commons Attribution-ShareAlike 4.0 International
License</span>")
autor <- glue("<span style='color:{c2};'>**Víctor Gauto**</span>")
icon_twitter <- glue("<span style='font-family:jet;'></span>")
icon_instagram <- glue("<span style='font-family:jet;'></span>")
icon_github <- glue("<span style='font-family:jet;'></span>")
icon_mastodon <- glue("<span style='font-family:jet;'>󰫑</span>")
icon_bsky <- glue("<span style='font-family:jet;'></span>")
usuario <- glue("<span style='color:{c2};'>**vhgauto**</span>")
sep <- glue("**|**")
mi_caption <- glue(
"{fuente}<br>{autor} {sep} {icon_github} {icon_twitter} {icon_instagram} ",
"{icon_mastodon} {icon_bsky} {usuario}"
)
Convierte la cantidad de torres por período a largo del segmento, para mostrar avance.
Generación y almacenamiento de cada mapa.
f_mapa <- function(año_mes) {
# contador para seguimiento en consola
l <- length(v_año_mes)
n <- which(v_año_mes == año_mes)
n <- case_when(
n <= 9 ~ glue("00{n}"),
n <= 99 ~ glue("0{n}"),
.default = glue("{n}")
)
print(glue("-- {n} de {l} --"))
# etiquetas de año y mes
año_label <- year(año_mes)
mes_label <- str_to_upper(format(año_mes, "%B"))
mi_title <- glue(
"<span style='font-size:20px;'>{año_label}</span><br>",
"<span style='font-size:10px;'>{mes_label}</span>")
# filtro los datos
e <- d |>
filter(primero <= año_mes)
# color de la leyenda
label_tbl <- count(e, radio) |>
mutate(color = paleta_radio[radio]) |>
mutate(label = glue("{radio}<br><span style='color:{color}'>{n}</span>")) |>
arrange(radio)
scale_color_names <- pull(label_tbl, radio)
scale_color_labels <- pull(label_tbl, label)
scale_color_values <- pull(label_tbl, color)
# extensión
d_l <- count(tibble(e), radio) |>
arrange(radio) |>
mutate(
x = eje_x_min,
xend = f_escala(n),
y = eje_y_radio[radio]
) |>
mutate(yend = y) |>
mutate(color = paleta_radio[radio])
# figura
g <- ggplot() +
# Argentina
geom_sf(data = arg_sf, fill = c5, color = NA, linewidth = .1) +
# torres de radio
geom_sf(data = e, aes(color = radio, size = radio), alpha = .5) +
# líneas horizontales
geom_segment(
data = d_l, aes(x, y, xend = xend, yend = yend), color = d_l$color,
linewidth = 1) +
# año
annotate(
geom = "text", x = I(.85), y = I(.95), label = año_label, vjust = 0,
family = "jet", size = 6, color = c3) +
# mes
annotate(
geom = "text", x = I(.85), y = I(.944), label = mes_label, vjust = 1,
family = "jet", size = 3, color = c3) +
scale_color_manual(
breaks = scale_color_names,
labels = scale_color_labels,
values = scale_color_values) +
scale_size_manual(values = c(.1, .4, .7)) +
labs(color = NULL, caption = mi_caption) +
coord_sf(
xlim = c(bb_sf$xmin, bb_sf$xmax),
ylim = c(bb_sf$ymin, bb_sf$ymax),
expand = FALSE) +
guides(
color = guide_legend(
position = "inside",
override.aes = list(size = 3, alpha = 1)),
size = guide_none()
) +
theme_void() +
theme(
plot.background = element_rect(fill = c4, color = c3, linewidth = 1),
plot.margin = margin(r = 4, b = 3, l = 4),
plot.caption = element_markdown(
family = "ubuntu", color = c1, size = 7, lineheight = unit(1.1, "line"),
margin = margin(t = -15, r = 5)),
legend.position.inside = c(0.6, 0.4),
legend.key.spacing.y = unit(.7, "line"),
legend.justification.inside = c(0, 1),
legend.text = element_markdown(family = "jet")
)
# guardo
ggsave(
plot = g,
filename = glue("./argentina/animaciones/torres_celulares/{n}.png"),
width = 1000,
height = 2140,
units = "px"
)
}
Los datos de las torres de celulares se encuentran en OpenCellid. Es requisito tener una cuenta para poder solicitar un token de acceso y descargar los datos.
d <- read_csv(
"./argentina/vectores/722X.csv",
col_names = 1:14,
col_select = c(1, 7, 8, 12, 13)) |>
rename(radio = X1, lon = X7, lat = X8, primero = X12, ultimo = X13) |>
mutate(primero = as_datetime(primero)) |>
mutate(ultimo = as_datetime(ultimo)) |>
mutate(primero = as.Date(primero)) |>
mutate(ultimo = as.Date(ultimo)) |>
mutate(año = year(primero), mes = month(primero)) |>
mutate(radio = fct(radio, levels = c("GSM", "UMTS", "LTE"))) |>
st_as_sf(coords = c("lon", "lat")) |>
st_set_crs(value = 4326) |>
st_transform(crs = 5346)
Vector de Argentina y contorno.
Extraigo los meses y años de la base de datos.
Paleta de colores por tipo de red.
Posición de cada segmento según tipo de torre.
eje_x_min <- bb_sf$xmax*.895
eje_x_max <- bb_sf$xmax*.99
# posición vertical, de los segmentos según tipo de radio
eje_y_gsm <- bb_sf$ymin*1.402
eje_y_umts <- eje_y_gsm - 2.22e5
eje_y_lte <- eje_y_gsm - 2*2.22e5
eje_y_radio <- c(eje_y_gsm, eje_y_umts, eje_y_lte)
names(eje_y_radio) <- c("GSM", "UMTS", "LTE")
Genero todas las figuras.
A partir de las figuras genero la animación.
Elimino la carpeta con todas las imágenes.
---
format:
html:
anchor-sections: true
code-fold: show
code-summary: "Ocultar código"
code-line-numbers: false
code-annotations: false
code-link: true
code-tools:
source: true
toggle: true
caption: "Código"
code-overflow: scroll
page-layout: full
editor_options:
chunk_output_type: console
categories: ["geom_sf", "geom_sf_pattern"]
execute:
eval: false
echo: true
warning: false
title: "Torres de telecomunicaciones"
date: 2024-02-17
author: Víctor Gauto
---
Animación del avance de las torres de telecomunicaciones en Argentina, entr 2009 y 2024, para redes GSM, UMTS y LTE.

## Paquetes
```{r}
library(glue)
library(showtext)
library(ggtext)
library(sf)
library(magick)
library(tidyverse)
```
## Estilos
Colores.
```{r}
c1 <- "#76BE72"
c2 <- "#F04C44"
c3 <- "#442224"
c4 <- "grey95"
c5 <- "grey92"
```
Fuentes: Ubuntu y JetBrains Mono.
```{r}
font_add(
family = "ubuntu",
regular = "././fuente/Ubuntu-Regular.ttf",
bold = "././fuente/Ubuntu-Bold.ttf",
italic = "././fuente/Ubuntu-Italic.ttf"
)
font_add(
family = "jet",
regular = "././fuente/JetBrainsMonoNLNerdFontMono-Regular.ttf"
)
showtext_auto()
showtext_opts(dpi = 300)
```
## Epígrafe
```{r}
fuente <- glue(
"Datos: <span style='color:{c2}; font-size: 8px'>**OpenCelliD Project** is
licensed under a Creative<br>Commons Attribution-ShareAlike 4.0 International
License</span>")
autor <- glue("<span style='color:{c2};'>**Víctor Gauto**</span>")
icon_twitter <- glue("<span style='font-family:jet;'></span>")
icon_instagram <- glue("<span style='font-family:jet;'></span>")
icon_github <- glue("<span style='font-family:jet;'></span>")
icon_mastodon <- glue("<span style='font-family:jet;'>󰫑</span>")
icon_bsky <- glue("<span style='font-family:jet;'></span>")
usuario <- glue("<span style='color:{c2};'>**vhgauto**</span>")
sep <- glue("**|**")
mi_caption <- glue(
"{fuente}<br>{autor} {sep} {icon_github} {icon_twitter} {icon_instagram} ",
"{icon_mastodon} {icon_bsky} {usuario}"
)
```
## Funciones
Convierte la cantidad de torres por período a largo del segmento, para mostrar avance.
```{r}
f_escala <- function(x) {
eje_x_min + x*(eje_x_max - eje_x_min)/l_max
}
```
Generación y almacenamiento de cada mapa.
```{r}
f_mapa <- function(año_mes) {
# contador para seguimiento en consola
l <- length(v_año_mes)
n <- which(v_año_mes == año_mes)
n <- case_when(
n <= 9 ~ glue("00{n}"),
n <= 99 ~ glue("0{n}"),
.default = glue("{n}")
)
print(glue("-- {n} de {l} --"))
# etiquetas de año y mes
año_label <- year(año_mes)
mes_label <- str_to_upper(format(año_mes, "%B"))
mi_title <- glue(
"<span style='font-size:20px;'>{año_label}</span><br>",
"<span style='font-size:10px;'>{mes_label}</span>")
# filtro los datos
e <- d |>
filter(primero <= año_mes)
# color de la leyenda
label_tbl <- count(e, radio) |>
mutate(color = paleta_radio[radio]) |>
mutate(label = glue("{radio}<br><span style='color:{color}'>{n}</span>")) |>
arrange(radio)
scale_color_names <- pull(label_tbl, radio)
scale_color_labels <- pull(label_tbl, label)
scale_color_values <- pull(label_tbl, color)
# extensión
d_l <- count(tibble(e), radio) |>
arrange(radio) |>
mutate(
x = eje_x_min,
xend = f_escala(n),
y = eje_y_radio[radio]
) |>
mutate(yend = y) |>
mutate(color = paleta_radio[radio])
# figura
g <- ggplot() +
# Argentina
geom_sf(data = arg_sf, fill = c5, color = NA, linewidth = .1) +
# torres de radio
geom_sf(data = e, aes(color = radio, size = radio), alpha = .5) +
# líneas horizontales
geom_segment(
data = d_l, aes(x, y, xend = xend, yend = yend), color = d_l$color,
linewidth = 1) +
# año
annotate(
geom = "text", x = I(.85), y = I(.95), label = año_label, vjust = 0,
family = "jet", size = 6, color = c3) +
# mes
annotate(
geom = "text", x = I(.85), y = I(.944), label = mes_label, vjust = 1,
family = "jet", size = 3, color = c3) +
scale_color_manual(
breaks = scale_color_names,
labels = scale_color_labels,
values = scale_color_values) +
scale_size_manual(values = c(.1, .4, .7)) +
labs(color = NULL, caption = mi_caption) +
coord_sf(
xlim = c(bb_sf$xmin, bb_sf$xmax),
ylim = c(bb_sf$ymin, bb_sf$ymax),
expand = FALSE) +
guides(
color = guide_legend(
position = "inside",
override.aes = list(size = 3, alpha = 1)),
size = guide_none()
) +
theme_void() +
theme(
plot.background = element_rect(fill = c4, color = c3, linewidth = 1),
plot.margin = margin(r = 4, b = 3, l = 4),
plot.caption = element_markdown(
family = "ubuntu", color = c1, size = 7, lineheight = unit(1.1, "line"),
margin = margin(t = -15, r = 5)),
legend.position.inside = c(0.6, 0.4),
legend.key.spacing.y = unit(.7, "line"),
legend.justification.inside = c(0, 1),
legend.text = element_markdown(family = "jet")
)
# guardo
ggsave(
plot = g,
filename = glue("./argentina/animaciones/torres_celulares/{n}.png"),
width = 1000,
height = 2140,
units = "px"
)
}
```
## Datos
Los datos de las torres de celulares se encuentran en [OpenCellid](https://www.opencellid.org/downloads.php). Es requisito tener una cuenta para poder solicitar un token de acceso y descargar los datos.
```{r}
d <- read_csv(
"./argentina/vectores/722X.csv",
col_names = 1:14,
col_select = c(1, 7, 8, 12, 13)) |>
rename(radio = X1, lon = X7, lat = X8, primero = X12, ultimo = X13) |>
mutate(primero = as_datetime(primero)) |>
mutate(ultimo = as_datetime(ultimo)) |>
mutate(primero = as.Date(primero)) |>
mutate(ultimo = as.Date(ultimo)) |>
mutate(año = year(primero), mes = month(primero)) |>
mutate(radio = fct(radio, levels = c("GSM", "UMTS", "LTE"))) |>
st_as_sf(coords = c("lon", "lat")) |>
st_set_crs(value = 4326) |>
st_transform(crs = 5346)
```
Vector de Argentina y contorno.
```{r}
arg_sf <- st_read("./argentina/vectores/arg_continental.gpkg") |>
st_transform(crs = 5346)
# extensión de Argentina, para ampliar el mapa
bb <- st_bbox(arg_sf)
ext <- terra::vect(arg_sf) |> terra::ext()
bb_sf <- terra::vect(ext*1.1, crs = "EPSG:5346") |>
st_as_sf() |>
st_bbox()
```
Extraigo los meses y años de la base de datos.
```{r}
v_año_mes <- tibble(d) |>
distinct(año, mes) |>
mutate(dia = 1) |>
mutate(fecha = make_date(year = año, month = mes, day = dia)) |>
arrange(fecha) |>
pull(fecha)
# máxima cantidad de torres de radio
l_max <- count(tibble(d), radio, sort = TRUE) |>
arrange(radio) |>
pull(n) |>
max()
```
## Figura
Paleta de colores por tipo de red.
```{r}
paleta_radio <- c(c1, c2, c3)
names(paleta_radio) <- c("GSM", "UMTS", "LTE")
```
Posición de cada segmento según tipo de torre.
```{r}
eje_x_min <- bb_sf$xmax*.895
eje_x_max <- bb_sf$xmax*.99
# posición vertical, de los segmentos según tipo de radio
eje_y_gsm <- bb_sf$ymin*1.402
eje_y_umts <- eje_y_gsm - 2.22e5
eje_y_lte <- eje_y_gsm - 2*2.22e5
eje_y_radio <- c(eje_y_gsm, eje_y_umts, eje_y_lte)
names(eje_y_radio) <- c("GSM", "UMTS", "LTE")
```
Genero todas las figuras.
```{r}
walk(v_año_mes, f_mapa)
beepr::beep(2)
Sys.sleep(1.5)
beepr::beep(2)
Sys.sleep(1.5)
beepr::beep(2)
Sys.sleep(1.5)
```
## Animación
A partir de las figuras genero la animación.
```{r}
av::av_encode_video(
input = list.files(
path = "./argentina/animaciones/torres_celulares/",
full.names = TRUE, pattern = ".png"
)[-c(1, 2)],
framerate = 7,
output = "./argentina/animaciones/torres_celulares.mp4"
)
```
Elimino la carpeta con todas las imágenes.
```{r}
unlink("./argentina/animaciones/torres_celulares/", recursive = TRUE)
```