Ocultar código
library(glue)
library(ggtext)
library(showtext)
library(terra)
library(tidyterra)
library(ggspatial)
library(patchwork)
library(tidyverse)Sitio en construcción
Víctor Gauto
2 de abril de 2026
Mapas RGB de las ciudades en las que ocurren los JJ. OO. de Invierno 2026, Milano y Cortina.

Colores.
Fuentes: Ubuntu y JetBrains Mono.
fuente <- glue(
"Datos: <span style='color:{c1};'><span style='font-family:jet;'>",
"{{<b>tidytuesdayR</b>}}</span> semana 06, ",
"<b>XXV Olympic Winter Games | Milano Cortina 2026</b>.</span>"
)
autor <- glue("<span style='color:{c1};'>**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:{c1};'>**vhgauto**</span>")
sep <- glue("**|**")
mi_caption <- glue(
"{fuente}<br>{autor} {sep} {icon_github} {icon_twitter} {icon_instagram} ",
"{icon_mastodon} {icon_bsky} {usuario}"
)Me interesa señalar las ciudades de los JJ.OO., Milano y Cortina, en un mapa de Italia, y mostrar mapas satelitales para cada una.
Creo un vector con el nombre de las ciudades, para obtener los datos y generar los mapas. Asigno colores, obtengo las coordenadas y creo vector.
ciudades <- c("Cortina d'Ampezzo", "Milano")
ciudades_col <- c(c1, c2)
ciudades_col <- set_names(ciudades_col, ciudades)
cortina <- c(12.137351, 46.538333)
milan <- c(9.19, 45.466944)
df <- data.frame(
lon = c(12.137351, 9.19),
lat = c(46.538333, 45.466944),
ciudad = ciudades
)
p <- vect(df, geom = c("lon", "lat"), crs = "EPSG:4326")Vectores de Italia y de las ciudades.
Función para generar un vector buffer circular alrededor de las ciudades.
Función para obtener ráster RGB de los buffer de las ciudades.
Ejecuto para ambas ciudades y asigno nombres.
Función para generar los mapas de cada ciudad.
f_gg <- function(X) {
colorX <- if (X == "Milano") ciudades_col[2] else ciudades_col[1]
locationX <- if (X == "Milano") "br" else "bl"
ggplot() +
geom_spatraster_rgb(
data = l_rgb[[X]],
maxcell = prod(dim(l_rgb[[X]]))
) +
geom_spatvector(
data = v[v$shapeName == X],
fill = NA,
color = colorX,
linetype = 1,
linewidth = .6
) +
geom_spatvector(
data = v[v$shapeName == X],
fill = NA,
color = c3,
linetype = 2,
linewidth = .6
) +
geom_spatvector(
data = f_bb(X),
fill = NA,
color = colorX,
linewidth = 1
) +
annotation_scale(
location = locationX,
bar_cols = c(c3, colorX),
height = unit(.2, "cm"),
line_col = colorX,
text_family = "jet"
) +
coord_sf(clip = "off") +
labs(title = X) +
theme_void(base_family = "ubuntu") +
theme_sub_plot(
title = element_text(
hjust = .5,
face = "bold",
size = 15,
color = colorX,
margin = margin_auto(0)
)
)
}Genero los mapas.
Mapa de Italia señalando las ciudades.
gg_it <- ggplot() +
geom_spatvector(
data = it1,
fill = c4,
color = c5,
linewidth = .2
) +
geom_spatvector(
data = v,
aes(fill = shapeName),
color = NA,
show.legend = FALSE
) +
annotate(
geom = "segment",
x = I(c(.48, .23)),
xend = I(c(.65, .1)),
y = I(c(.92, .84)),
yend = I(c(.98, .95)),
arrow = arrow(angle = 20, length = unit(5, "pt"), type = "closed")
) +
annotate(
geom = "label",
x = I(c(.65, .1)),
y = I(c(.98, .95)),
label = ciudades,
fill = NA,
border.color = NA,
fontface = "bold",
family = "ubuntu",
hjust = .5,
vjust = 0,
color = ciudades_col,
size = 3
) +
coord_sf(clip = "off", expand = TRUE) +
scale_fill_manual(
values = ciudades_col
) +
theme_void()Logo de los JJ. OO. para incorporar a la figura.
Combino los mapas y agrego el logo.
g <- wrap_plots(
list(gg_it, l_gg[[1]], l_gg[[2]]),
nrow = 1
) +
annotation_custom(
ggsvg::svg_to_rasterGrob(logo_txt),
xmin = I(-2),
xmax = I(-2.3),
ymin = I(.2),
ymax = I(-.1)
) &
plot_annotation(
title = glue(
"Durante los <b style='color:{c1};'>JJ. OO. de Invierno 2026</b> se van a disputar <b style='color:{c2};'>{nrow(schedule)}</b> eventos deportivos"
),
caption = mi_caption,
theme = theme(
plot.title = element_markdown(
family = "ubuntu",
size = 21,
hjust = .5,
margin = margin_auto(10)
),
plot.caption = element_markdown(
family = "ubuntu",
color = c2,
size = 8,
lineheight = 1.3,
margin = margin(t = 5, b = 3)
),
plot.background = element_rect(fill = c6, color = NA)
)
)Guardo.
---
format:
html:
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_spatraster_rgb
- geom_spatvector
execute:
eval: false
echo: true
warning: false
title: "Semana 06"
date: last-modified
author: Víctor Gauto
---
Mapas RGB de las ciudades en las que ocurren los **JJ. OO. de Invierno 2026**, Milano y Cortina.
::: {.column-screen-inset}

:::
## Paquetes
```{r}
library(glue)
library(ggtext)
library(showtext)
library(terra)
library(tidyterra)
library(ggspatial)
library(patchwork)
library(tidyverse)
```
## Estilos
Colores.
```{r}
c1 <- "#05a3bd"
c2 <- "#da7900"
c3 <- "white"
c4 <- "grey95"
c5 <- "grey30"
c6 <- "grey98"
```
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:{c1};'><span style='font-family:jet;'>",
"{{<b>tidytuesdayR</b>}}</span> semana 06, ",
"<b>XXV Olympic Winter Games | Milano Cortina 2026</b>.</span>"
)
autor <- glue("<span style='color:{c1};'>**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:{c1};'>**vhgauto**</span>")
sep <- glue("**|**")
mi_caption <- glue(
"{fuente}<br>{autor} {sep} {icon_github} {icon_twitter} {icon_instagram} ",
"{icon_mastodon} {icon_bsky} {usuario}"
)
```
## Datos
```{r}
tuesdata <- tidytuesdayR::tt_load(2026, 06)
schedule <- tuesdata$schedule
```
## Procesamiento
Me interesa señalar las ciudades de los JJ.OO., Milano y Cortina, en un mapa de Italia, y mostrar mapas satelitales para cada una.
Creo un vector con el nombre de las ciudades, para obtener los datos y generar los mapas. Asigno colores, obtengo las coordenadas y creo vector.
```{r}
ciudades <- c("Cortina d'Ampezzo", "Milano")
ciudades_col <- c(c1, c2)
ciudades_col <- set_names(ciudades_col, ciudades)
cortina <- c(12.137351, 46.538333)
milan <- c(9.19, 45.466944)
df <- data.frame(
lon = c(12.137351, 9.19),
lat = c(46.538333, 45.466944),
ciudad = ciudades
)
p <- vect(df, geom = c("lon", "lat"), crs = "EPSG:4326")
```
Vectores de Italia y de las ciudades.
```{r}
it4 <- rgeoboundaries::geoboundaries(country = "ITA", adm_lvl = 4) |>
terra::vect()
it1 <- rgeoboundaries::geoboundaries(country = "ITA", adm_lvl = 1) |>
terra::vect()
v <- it4[it4$shapeName %in% ciudades]
```
Función para generar un vector buffer circular alrededor de las ciudades.
```{r}
f_bb <- function(X) {
v <- v[v$shapeName == X]
centro <- centroids(v)
buffer(centro, width = width(v) * .8, quadsegs = 1000)
}
```
Función para obtener ráster RGB de los buffer de las ciudades.
```{r}
f_rgb <- function(X) {
b <- f_bb(X)
maptiles::get_tiles(
x = b,
provider = "Esri.WorldImagery",
crop = TRUE,
zoom = 13
) |>
mask(b)
}
```
Ejecuto para ambas ciudades y asigno nombres.
```{r}
l_rgb <- map(ciudades, f_rgb)
l_rgb <- set_names(l_rgb, ciudades)
```
## Figura
Función para generar los mapas de cada ciudad.
```{r}
f_gg <- function(X) {
colorX <- if (X == "Milano") ciudades_col[2] else ciudades_col[1]
locationX <- if (X == "Milano") "br" else "bl"
ggplot() +
geom_spatraster_rgb(
data = l_rgb[[X]],
maxcell = prod(dim(l_rgb[[X]]))
) +
geom_spatvector(
data = v[v$shapeName == X],
fill = NA,
color = colorX,
linetype = 1,
linewidth = .6
) +
geom_spatvector(
data = v[v$shapeName == X],
fill = NA,
color = c3,
linetype = 2,
linewidth = .6
) +
geom_spatvector(
data = f_bb(X),
fill = NA,
color = colorX,
linewidth = 1
) +
annotation_scale(
location = locationX,
bar_cols = c(c3, colorX),
height = unit(.2, "cm"),
line_col = colorX,
text_family = "jet"
) +
coord_sf(clip = "off") +
labs(title = X) +
theme_void(base_family = "ubuntu") +
theme_sub_plot(
title = element_text(
hjust = .5,
face = "bold",
size = 15,
color = colorX,
margin = margin_auto(0)
)
)
}
```
Genero los mapas.
```{r}
l_gg <- map(ciudades, f_gg)
```
Mapa de Italia señalando las ciudades.
```{r}
gg_it <- ggplot() +
geom_spatvector(
data = it1,
fill = c4,
color = c5,
linewidth = .2
) +
geom_spatvector(
data = v,
aes(fill = shapeName),
color = NA,
show.legend = FALSE
) +
annotate(
geom = "segment",
x = I(c(.48, .23)),
xend = I(c(.65, .1)),
y = I(c(.92, .84)),
yend = I(c(.98, .95)),
arrow = arrow(angle = 20, length = unit(5, "pt"), type = "closed")
) +
annotate(
geom = "label",
x = I(c(.65, .1)),
y = I(c(.98, .95)),
label = ciudades,
fill = NA,
border.color = NA,
fontface = "bold",
family = "ubuntu",
hjust = .5,
vjust = 0,
color = ciudades_col,
size = 3
) +
coord_sf(clip = "off", expand = TRUE) +
scale_fill_manual(
values = ciudades_col
) +
theme_void()
```
Logo de los JJ. OO. para incorporar a la figura.
```{r}
logo <- "https://upload.wikimedia.org/wikipedia/commons/7/71/2026_Winter_Olympics_logo_%28Energy%29.svg"
logo_txt <- paste(readLines(logo), collapse = "\n")
```
Combino los mapas y agrego el logo.
```{r}
g <- wrap_plots(
list(gg_it, l_gg[[1]], l_gg[[2]]),
nrow = 1
) +
annotation_custom(
ggsvg::svg_to_rasterGrob(logo_txt),
xmin = I(-2),
xmax = I(-2.3),
ymin = I(.2),
ymax = I(-.1)
) &
plot_annotation(
title = glue(
"Durante los <b style='color:{c1};'>JJ. OO. de Invierno 2026</b> se van a disputar <b style='color:{c2};'>{nrow(schedule)}</b> eventos deportivos"
),
caption = mi_caption,
theme = theme(
plot.title = element_markdown(
family = "ubuntu",
size = 21,
hjust = .5,
margin = margin_auto(10)
),
plot.caption = element_markdown(
family = "ubuntu",
color = c2,
size = 8,
lineheight = 1.3,
margin = margin(t = 5, b = 3)
),
plot.background = element_rect(fill = c6, color = NA)
)
)
```
Guardo.
```{r}
ggsave(
plot = g,
filename = "tidytuesday/2026/semana_06.png",
width = 30,
height = 12,
units = "cm"
)
```