Periodismo de datos

Jaime Gutiérrez @jaimegutierrezh

Antes de empezar

¿Qué vamos a ver?

  • Introducción al periodismo de datos ✅

  • Presentación periodística de datos, hechos y cifras

  • Narrativas visuales

  • Herramientas del periodista de datos

Presentación periodística de datos, hechos y cifras

¿Por qué incluir gráficos en las piezas?

Los datos hablan por sí solos

“El mejor gráfico debe estar libre de cualquier distracción y permitirá que el lector compare y contraste los datos para sacar una conclusión”.

Dona M. Wong. Vicepresidenta de Comunicación del Banco de la Reserva Federal de Nueva York

Texto vs. gráfico

La empresa A tiene un beneficio anual de 100 millones de euros frente a la B, que ha logrado solo 75 millones.

  • Los números de un gráfico muestran la información de forma visual y narrativa

  • Refuerzan la idea que se quiere transmitir con el texto

  • Permite comparar los datos con un golpe de vista

  • Es un refuerzo visual o un complemento para la locución

  • “Un gráfico bien elegido vale más que mil palabras, proporciona comprensión y claridad en un mundo confuso” (Tim Harford, economista)

Para ofrecer contexto

El euribor está en el 4,074%

Para ofrecer contexto

El euribor alcanzó en octubre de 2023 el 4,16%, su nivel más elevado desde noviembre de 2008, tras el estallido de la burbuja inmobiliaria.

  • Un solo número no dice mucho, pero una serie en un gráfico puede contar una historia

  • Sirve para detectar y mostrar tendencias

  • Ofrecer referencias permite controlar el mensaje

Los datos nos pueden contar una historia

Lo que 15.000 alarmas cuentan de la Guerra de Ucrania

El País

Rusia emprendió el asalto a la capital de Ucrania con brutalidad: hubo más de cien sirenas solo en la segunda quincena de marzo.

Fracasada la toma de Kiev, y tras un verano con menos ataques, el 8 de octubre, la destrucción del puente que unía Crimea y Rusia provocó una nueva ofensiva del Kremlin.

El 25 de enero, solo en Kiev sonaron cinco alarmas que advertían del impacto de los 30 misiles lanzados por Rusia en respuesta al compromiso de EE.UU. y Alemania de enviar tanques a Ucrania.

Battling Infectious Diseases in the 20th Century: The Impact of Vaccines, Wall Street Journal

Battling Infectious Diseases in the 20th Century: The Impact of Vaccines, Wall Street Journal

⚠️ Los datos pueden cambiar tu punto de vista

⚠️ Los datos pueden cambiar tu punto de vista

🚨 Los datos pueden engañarnos

Suspicious Correlations

Suspicious Correlations

Warning

Correlación NO implica causalidad

Buenas prácticas para presentar datos, hechos y cifras

¿Qué es más eficiente?

Xaquín Veira González

Todo es relativo

Cuenta la historia completa (I)

Cuenta la historia completa (II)

Note

El mensaje debe ser consistente con todos los datos relevantes para la historia

Haz comparaciones justas (I)

Warning

Si dos gráficos se presentan juntos, se crea una comparación.

Haz comparaciones justas (II)

Tip

Usa escalas comparables. El eje de cada gráfico representa el mismo cambio porcentual para que la variación se perciba por la inclinación de las líneas.

Haz comparaciones justas (III)

País
Nº tarjetas de crédito (millones)
A 100
B 300
C 400

Haz comparaciones justas (IV)

País
Nº tarjetas de crédito (millones)
A 100
B 300
C 400

Haz comparaciones justas (V)

País Nº tarjetas de crédito (millones) Población (millones) Nº tarjetas per cápita
A 100 200 0,5
B 300 200 1,5
C 400 400 1

Haz comparaciones justas (VI)

País Nº tarjetas de crédito (millones) Población (millones) Nº tarjetas per cápita
A 100 200 0,5
B 300 200 1,5
C 400 400 1

Tip

Si los datos de origen son insuficientes ❌ No le añadas elementos decorativos ✅ Busca fuentes adicionales y ajusta los datos para hacerlos comparables

Los números índices

  • Los números índices son útiles para realizar comparaciones de magnitudes en el tiempo o en el espacio.

  • Sirven para medir variaciones y permiten mostrar una evolución temporal o una comparación entre territorios fijando un valor como base.

  • El IPC no expresa precios en euros, sino las variaciones de esos precios el % para analizar su evolución a lo largo del tiempo.

Trata de mostrar la realidad

  • El propósito de un gráfico de líneas es mostrar una tendencia

  • Elegir una escala que aplana la curva desvirtúa el propósito del gráfico

  • Exagerar la escala crea un dramatismo que puede ser injusto con la realidad

Usa escalas naturales (I)

Usa escalas naturales (II)

¡Cuidado al truncar el eje! (I)

  • Los gráficos de línea no siempre necesitan empezar en cero

  • Aunque hay que incluir la línea de base si los datos están cerca de ella

  • También es útil mostrar el 0 y el 100% con porcentajes

¡Cuidado al truncar el eje! (II)

¡Cuidado al truncar el eje! (III)

Warning

Los gráficos que muestran o comparan volúmenes entre sí siempre deben comenzar en cero

Ordena y reagrupa (I)

  • La cualidad principal de un gráfico de barras es que crea un ranking

  • Ordenar las barras de mayor a menor (o viceversa) facilita la lectura

  • También puedes destacar una de las barras para reforzar el relato

Ordena y reagrupa (II)

Hay algunas excepciones:

Leyendas y anotaciones (I)

  • Una leyenda separada de las líneas obliga a trabajar más al espectador

  • Nunca incluyas anotaciones largas y utiliza solo las necesarias

Leyendas y anotaciones (II)

  • Las etiquetas junto a las líneas permiten una identificación rápida y directa

  • Las anotaciones han de ser claras y concisas

Defensa contra los gráficos deshonestos

Los gráficos son una ventana al mundo. Cuando están bien hechos, nos enseñan a entender quiénes somos, dónde estamos y cómo podemos convertirnos en una versión mejor de nosotros mismos. Sin embargo, cuando están mal hechos, en ausencia de verdad, los gráficos pueden ser dañinos. Nathan Yau, Flowingdata

Cómo elegir el gráfico apropiado para cada dato

tipologías y usos

¿Qué historia quieres contar?

Gráfico de línea Gráfico de áreas Gráfico de líneas múltiple
Si solo tienes una variable Si tienes más de una variable y forman parte de un todo Si tienes múltiples variables que no forman un todo pero comparten una unidad de medida
Gráfico de columnas Columnas apiladas / stacked / treemap Mapas de coropletas
Magnitud en el tiempo Un todo y sus partes Considerando la geografía
Diagrama de dispersión Histograma
Mostrar relación entre dos variables Mostrar la distribución de una sola variable o de varias
Diagrama de Sankey Diagrama de cuerdas
Muestra los flujos de un sistema Muestra relaciones ponderadas y flujos entre nodos

Gráficos para comparar magnitudes

Columnas/barras

  • Los gráficos de barras pueden ser simples o apiladas y pueden mostrar valores absolutos o relativos

  • Las columnas apiladas sirven para mostrar un todo y sus partes

  • Las barras o columnas apiladas se pueden usar con intervalos temporales, pero estos deben ser iguales

  • Los gráficos de área son una alternativa similar cuando los intervalos temporales son distintos

  • Elige las columnas si las etiquetas de los datos son cortas y las barras si son algo más largas

  • NUNCA incluyas el total en tu gráfico apilado, solo las partes que lo componen

Columnas/barras

¿Cómo mejoramos este gráfico?

Columnas/barras

¿Cómo mejoramos este gráfico?

  1. Ordenamos de mayor a menor, con el grupo más numeroso pegado al eje.

Columnas/barras

¿Cómo mejoramos este gráfico?

  1. Ordenamos de mayor a menor, con el grupo más numeroso pegado al eje.

  2. Agrupo las categorías menos importantes en “Otros”.

Columnas/barras

¿Cómo mejoramos este gráfico?

  1. Ordenamos de mayor a menor, con el grupo más numeroso pegado al eje.

  2. Agrupo las categorías menos importantes en “Otros”.

  3. Aplicamos una paleta de colores más limpia.

Columnas/barras

¿Cómo mejoramos este gráfico?

  1. Ordenamos de mayor a menor, con el grupo más numeroso pegado al eje.

  2. Agrupo las categorías menos importantes en “Otros”.

  3. Aplicamos una paleta de colores más limpia.

  4. Calculamos porcentajes para poder comparar.

Columnas/barras

¿Cómo mejoramos este gráfico?

  1. Ordenamos de mayor a menor, con el grupo más numeroso pegado al eje.

  2. Agrupo las categorías menos importantes en “Otros”.

  3. Aplicamos una paleta de colores más limpia.

  4. Calculamos porcentajes para poder comparar.

  5. Destacamos una variable y reordenamos.

Columnas/barras

¿Cómo mejoramos este gráfico?

  1. Ordenamos de mayor a menor, con el grupo más numeroso pegado al eje.

  2. Agrupo las categorías menos importantes en “Otros”.

  3. Aplicamos una paleta de colores más limpia.

  4. Calculamos porcentajes para poder comparar.

  5. Destacamos una variable y reordenamos.

  6. Colocamos la leyenda junto a las barras.

Tarta/donut

  • Sirven para mostrar las partes de un todo (100%)

  • Funcionan mejor con datos alrededor del 25, 50 o 75%, más fáciles de reconocer

  • Reduce el número de valores agrupando las partes más pequeñas

  • Destaca el valor más importante y usa un degradado para el resto

  • Como en las líneas y las barras, coloca etiquetas directas en vez de leyenda

Tarta/donut

  • Sirven para mostrar las partes de un todo (100%)

  • Funcionan mejor con datos alrededor del 25, 50 o 75%, más fáciles de reconocer

  • Reduce el número de valores agrupando las partes más pequeñas

  • Destaca el valor más importante y usa un degradado para el resto

  • Como en las líneas y las barras, coloca etiquetas directas en vez de leyenda

Tip

Si pretendes que el lector compare el tamaño de cada parte, opta mejor por un gráfico de barras. Sobre todo si las diferencias son pequeñas

Tarta/donut

Los gráficos de tarta se leen como un reloj. Coloca los valores de mayor a menor hacia la derecha desde las 12 en punto. Puedes dejar la categoria “Otros” al final.

Treemap

  • Organización jerárquica de los datos

  • Solo cuando hay subcategorías anidadas

  • Cada rectángulo ocupa un área proporcional a la cantidad de datos que representa

Tip

Un buen treemap contiene: valores positivos que forman parte de un todo y que son agrupables por categorías y niveles.❌ Nunca incluyas en tu treemap valores negativos

Pictogramas

  • Los pictogramas ofrecen un vistazo rápido de cantidades y volúmenes, pero no sirven para mostrar datos masivos

  • Las barras son más eficientes para comparar cantidades discretas

  • Los iconos deben ser simples, simétricos y funcionar bien en tamaños pequeños

Mala elección

Buena elección

Pictogramas

No deformes los pictogramas para transformarlos en barras/columnas. El tamaño debe ser proporcional en cuanto al área.

Pictogramas

  • Utiliza unidades naturales.

  • Asigna un valor al icono y divide los datos en unidades que sean múltiplo de ese valor.

  • Evita partir los iconos. Si tus datos no encajan con esta división, las barras o las columnas son mejor opción.

Pictogramas

Si los datos que vas a comparar están muy juntos, no uses pictogramas.

Rangos de puntos

  • Una buena elección para mostrar la diferencia entre dos variables

  • Además de una comparación en horizontal, permite comparar en vertical

Gráficos para observar cambios en el tiempo

Curvas

  • Usa gráficos de líneas cuando quieras mostrar la evolución de unos datos

  • Los gráficos de líneas permiten comparar categorías entre sí

  • Funcionan con series de datos largas que evolucionan de forma continua

Áreas

  • Si las categorías forman parte de un todo, es mejor el gráfico de área

Áreas apiladas

  • Apilar los valores absolutos permite que los lectores vean cómo ha cambiado la distribución de las categorías a lo largo del tiempo.

El mundo como 100 personas

Max Roser

Slopes

  • Es el mejor gráfico si tienes pocos datos

  • Pone el foco en el principio y el final del periodo temporal

  • Permite etiquetar casi todas las líneas

  • Puedes usar el color para señalar las subidas y bajadas

Variación porcentual

  • Otra forma de mostrar la evolución de un dato es visualizando su variación porcentual

Barras divergentes

Flechas

Heatmap (I)

  • Útiles para mostrar datos agrupados en intervalos

  • Muestran de un vistazo la evolución de una serie histórica

Heatmap (II)

Warning

Comparados con un gráfico de líneas, los heatmaps hacen más difícil cuantificar cada dato por separado

Calendario de burbujas

  • Eficaces para comparar magnitudes en periodos de tiempo concretos

  • Muy útiles para datos de desastres naturales

Gráficos para mostrar flujos

Diagrama de cuerdas

Sankey

Gráficos de distribución y dispersión

Histogramas

  • Su forma nos indica la distribución de los datos

Pirámides de población

Diagramas de dispersión o scatterplots

  • La correlación nos permite ver hasta qué punto dos sucesos pueden estar relacionados.

  • Cada punto está situado en las coordenadas de sus valores “x” e “y”.

  • Por convención, el eje “x” se reserva para la variable explicativa (independiente) y el “y” para la que se quiere explicar (dependiente).

  • Ojo: situar una variable en cada eje no demuestra que una cause la otra.

Claves

  • 🍋 Aprovecha lo que tienes

  • 🧠 Entiende los datos

  • ✅ ✅ Comprueba y vuelve a comprobar

  • 📖 Cuenta una historia

  • 🔍 Pregúntale a ChatGPT (o a Google)

¡Gracias!

Continuará…

Ver Narrativas visuales

#| echo: false
#| label: libraries
library(tidyverse)

# Fondo transparente en todos los gráficos para que encajen con el crema de las diapositivas
.bg_transparente <- theme(
  plot.background   = element_rect(fill = "transparent", colour = NA),
  panel.background  = element_rect(fill = "transparent", colour = NA),
  legend.background = element_rect(fill = "transparent", colour = NA),
  legend.key        = element_rect(fill = "transparent", colour = NA)
)
theme_minimal <- function(...) ggplot2::theme_minimal(...) + .bg_transparente
theme_set(theme_grey() + .bg_transparente)

¡Hola, otra vez!

Antes de empezar

¿Qué vamos a ver?

  • Introducción al periodismo de datos ✅

  • Presentación periodística de datos, hechos y cifras ✅

  • Narrativas visuales

  • Herramientas del periodista de datos

Narrativas visuales

El periodismo visual más allá de los datos

  • El periodismo visual conlleva la exposición de los hechos mediante la representación gráfica.

  • El periodismo de datos incorpora métodos de las ciencias sociales a la práctica periodística.

  • En el periodismo interactivo, el público deja de ser un mero lector y se le pide ejecutar acciones para lograr objetivos.

Equipo de narrativas visuales en la redacción

Las fronteras se diluyen y los profesionales consideran su cometido primordial hacer periodismo más allá de su especialización.

  • Periodistas

  • Infografistas

  • Desarrolladores

  • Diseñadores

  • Realizadores

  • Analistas y científicos de datos

  • Cartógrafos

Infografía ≠ visualización de datos (I)

  • La infografía es una creación elaborada ad hoc con variedad de recursos para transmitir una información.

  • La visualización de datos implica una codificación visual que aporta información cuantitativa e identifica patrones y tendencias.

  • La infografía puede tener propiedades cualitativas, cuantitativas o narrativas, como la explicación de un proceso.

Infografía ≠ visualización de datos (II)

  • La infografía puede incorporar recursos de otros lugares, incluida la visualización de datos.

  • En el entorno digital, infografía es sinónimo de narrativa visual que combina diferentes formas de comunicación: el texto, la voz, la animación, la ilustración, visualizaciones de datos, 3D…

El lenguaje infográfico

Gráficos

Nadal renuncia a ‘su’ Roland Garros (DatosRTVE)

Nadal renuncia a ‘su’ Roland Garros (DatosRTVE)

Mapas

Tracking the Russian Invasion of Ukraine (The New York Times)

Tracking the Russian Invasion of Ukraine (The New York Times)

Localizadores

Reconstruir Ucrania cuando aún caen las bombas (DatosRTVE)

Reconstruir Ucrania cuando aún caen las bombas (DatosRTVE)

Esquemas

¿Qué se sabe del edificio incendiado en Valencia? (DatosRTVE)

¿Qué se sabe del edificio incendiado en Valencia? (DatosRTVE)

Ilustración fáctica

Buried under the bricks (Reuters Graphics)

Buried under the bricks (Reuters Graphics)

Ilustración decorativa

Alcaraz, una carrera fulgurante y otro gran título para emular al ‘Big Three’ del tenis (DatosRTVE)

Alcaraz, una carrera fulgurante y otro gran título para emular al ‘Big Three’ del tenis (DatosRTVE)

Interactividad

Más de 65 kilos de comida por familia terminan en la basura (DatosRTVE)

Más de 65 kilos de comida por familia terminan en la basura (DatosRTVE)

Animación, vídeo y sonido

Periodismo inmersivo

Realidad virtual, realidad aumentada y 3D

Scrollytelling

Narrativa cohesiva de eventos a través del tiempo en la que el usuario avanza mediante el scroll.

Memorias del 11M: regreso al peor día de nuestras vidas

Memorias del 11M: regreso al peor día de nuestras vidas

El proceso creativo

Del boceto…

…al resultado

Herramientas del periodista visual

Herramientas del periodista visual

  • Mapas de localización (Datawrapper)

  • Timeline (Flourish)

  • Imágenes satélite (Sentinel y Maxar)

  • Antes y después (Flourish)

  • Quizzes y continúa la línea (Flourish)

  • Calculadoras (Flourish)

  • Encuestas (Flourish)

  • Contadores (Flourish)

  • Mapbox, 3D y realidad aumentada

El color en la visualización de datos

No uses demasiados colores

  • Si tu gráfico necesita más de siete colores, considera utilizar otro tipo de visualización o agrupar los datos en nuevas categorías.

Mantén la consistencia…

  • Sé consistente con el uso del color en todos tus gráficos.

…y la coherencia visual

  • Y mantén la coherencia visual del conjunto.

Tres páginas del The South China Morning Post

Pon el foco en lo importante

  • A veces, el gris nos puede ayudar a ofrecer contexto sin abrumar.

Los colores tienen significado

  • Usa el color de manera intuitiva y ten en cuenta su significado cultural para la audiencia.

El rosa y azul está bien, pero…

Variables continuas y categóricas

  • No uses gradientes de color para variables categóricas, y viceversa.

Grupos y subgrupos

  • Puedes usar gradientes para distinguir subgrupos dentro de categorías.

Población en territorios ocupados por religión (The Economist)

La intensidad del color también informa

  • Usa colores claros para valores bajos y oscuros para valores altos.

Cada dato requiere una escala de color

Secuencial. Cuando tengas datos cuantitativos y quieras destacar los valores más altos

Divergente. Cuando tengas datos cuantitativos y quieras poner el foco en los dos extremos de la escala

Cualitativa o categórica. Cuando los datos no son cuantitativos

Escalas

  • Usa escalas divergentes cuando haya un punto medio con un significado. Puede ser 0, 50%, la media o la mediana, un objetivo a alcanzar… Y ten en cuenta que pone el énfasis en los extremos.

Ten en cuenta a las personas daltónicas (I)

Ten en cuenta a las personas daltónicas (II)

  • El color azul es el más seguro porque es el que todos vemos de una forma más homogénea y puedes mezclarlo con naranja o rojo .

  • Los daltónicos al rojo lo percibirán como azul y verde oliva /.

  • Los daltónicos al verde lo percibirán como azul y naranja /.

  • Los daltónicos al azul lo percibirán como verde azulado y rosa /.

Tres herramientas para crear paletas de color

Cartografía y mapas

Sistemas de coordenadas (I)

  • Los mapas utilizan sistemas de coordenadas como un marco de referencia para definir las localizaciones que incluyen.

  • Uno de los sistemas de coordenadas más conocidos es el cartesiano.

Sistemas de coordenadas (II)

Algunas consideraciones sobre los sistemas de coordenadas:

  • Representan la superficie de la Tierra y utilizan puntos para representar la información geográfica.

  • Sus líneas de referencia son curvas.

  • Cada punto se localiza utilizando solo dos dimensiones: latitud y longitud.

Proyecciones (I)

  • Cuando presentas un mapa al lector, le estás pidiendo que compare entre sí las distintas partes del mapa.

  • Las diferentes proyecciones conservan distintas propiedades. La más importante al visualizar datos es el área.

  • Debes seleccionar una proyección que garantice la proporcionalidad entre las áreas.

  • El sistema de coordenadas geográficas más extendido es WGS84 (latitud/longitud sobre el elipsoide), identificado como EPSG:4326.

  • La proyección estándar de los mapas web es Web Mercator (EPSG:3857), que popularizó Google Maps en 2005. Conserva las formas, pero distorsiona las áreas hacia los polos, así que para visualizar datos suele convenir una proyección de igual área.

Proyecciones (II)

Geo Awesomeness

Datos espaciales y geométricos (I)

Es la información que describe la localización y la forma de un elemento en el mundo real. Puede ser de distintos tipos:

  • Vectores: ubicaciones y extensiones geográficas discretas.

  • Raster: ubicaciones aproximadas asignando cada una a las celdas de una cuadrícula o matriz. Por su reducido tamaño, sirven para representar variaciones continuas de los atributos.

Azavea

Datos espaciales y geométricos (II)

Tres tipos de vectores

Puntos Tienen ubicación pero no extensión (oficinas de correos).

Líneas Representan una geometría lineal a partir de puntos conectados (fronteras).

Polígonos Áreas completamente encerradas por líneas cuyos puntos inicial y final coinciden (países, provincias…).

Datos espaciales y geométricos (III)

Fuentes de datos cartográficos:

El formato importa

QGIS y Mapshaper

Comunicar con mapas

Tres tipos de mapas

Mapas coropléticos

Mapas de símbolos

Localizadores

Localizadores o mapas de ubicación

  • Los localizadores son mapas estáticos y simples que se usan para ubicar una región concreta en un contexto geográfico
  • Ayudan al usuario a familiarizarse con las particularidades de una localización que quizás no conocen de antemano
  • Pueden ser muy generales, para explicar la localización de un país en su contexto geográfico, o muy específicos, para ubicar la calle en la que ha ocurrido un suceso y su área circundante

Mapas de símbolos

#| echo: false
#| fig.show: true
#| fig.width: 15  # Aumenta el ancho
#| fig.height: 10   # Aumenta la altura
#| fig.bg: transparent
#| label: symbol-map

library(sf)

coordenadas_mun <- 
  read_csv2("carto/coordenadas_ciudades_es.csv") |> 
  janitor::clean_names() |> 
  select(mun = poblacion, lat = latitud, lon = longitud) |> 
  mutate(mun = case_when(
  mun == "Alicante/Alacant" ~ "Alacant/Alicante",
  mun == "Castellón de la Plana/Castelló de la Plana" ~ "Castelló de la Plana",
  mun == "Coruña (A)" ~ "A Coruña",
  mun == "Donostia-San Sebastián" ~ "Donostia/San Sebastián",
  mun == "Palmas de Gran Canaria (Las)" ~ "Las Palmas de Gran Canaria",
  mun == "Valencia" ~ "València",
  TRUE ~ mun))

pob_capitales_es <- 
  read_csv2("data/poblacion_capitales_provincia_es.csv",
            locale = locale(encoding = "latin1")) |> 
  janitor::clean_names() |> 
  mutate(mun = str_sub(capitales_de_provincia, 7, 100),
         mun = case_when(mun == "Coruña, A" ~ "A Coruña",
                         mun == "Palmas de Gran Canaria, Las" ~ "Las Palmas de Gran Canaria",
                         TRUE ~ mun),
         cod_ine = str_sub(capitales_de_provincia, 1, 7),
         bines = cut(total, breaks = c(0, 200000, 400000, 500000, 1000000, 2000000, 3000000, 4000000),
                     labels = c("≤ 200k", "200k - 400k", "400k - 500k", "1M - 2M", "2M - 3M", "3M+", "3M+"),
                     include.lowest = TRUE)) |> 
  select(mun, cod_ine, pob = total, bines) |> 
  filter(!mun %in% c("Las Palmas de Gran Canaria",
                     "Santa Cruz de Tenerife")) |> 
  left_join(coordenadas_mun, by = "mun") |> 
  sf::st_as_sf(coords = c("lon", "lat"), crs = 4326) 

mapa_es_provincias <- 
  st_read("carto/ccaa_es.geojson", quiet = TRUE) |> 
  st_transform(crs = 4326) |> 
  filter(Name != "Islas Canarias")

mas_pobladas <- 
  pob_capitales_es |> 
  slice_max(pob, n = 10) |> 
  pull(mun)

city_labels <- 
  coordenadas_mun |> 
  filter(mun %in% mas_pobladas)

ggplot() +
  # Mapa base
  geom_sf(data = mapa_es_provincias, 
          fill = "gray99", color = "grey30") + 
  # Puntos
  geom_sf(data = pob_capitales_es, 
          aes(size = pob), color = "#C1440E", alpha = 0.7) +
  # Ajustar tamaño de los símbolos
  scale_size_continuous(range = c(10, 40),
                        labels = scales::label_number(),
                        name = "Población") +
  # Etiquetas
  geom_text(data = city_labels, 
            aes(x = lon, y = lat, label = mun), 
            size = 7) + 
  labs(title = "Población de las capitales españolas en 2021", caption = "Fuente: INE", x = "", y = "") +
  theme_minimal() +
  theme(panel.grid = element_blank(),
        axis.text = element_blank(),
        title = element_text(size = 30),
        legend.text = element_text(size = 20),
        plot.caption = element_text(hjust = 0.1))
  • Son mapas en los que el dato sobre una localización específica, como una ciudad, se representa con formas geométricas
  • Requieren que la información (categórica o secuencial) esté asociada a una dirección o coordenadas geográficas (latitud/longitud)

Warning

No uses mapas de símbolos si quieres mostrar las diferencias entre áreas como países o regiones. Para eso existen los mapas de coropletas.

Mapas de coropletas

  • Ofrecen una visión general, pero dan poco detalle

  • Útiles para mostrar/investigar un patrón geográfico en los datos

#| echo: false
#| fig.show: true
#| fig.width: 15  # Aumenta el ancho
#| fig.height: 15   # Aumenta la altura
#| fig.bg: transparent
#| label: arope-map

library(sf)
tasa_arope <- 
  read_csv2("data/tasa_arope.csv") |> 
  janitor::clean_names() |> 
  drop_na(x1) |> 
  mutate(x1 = case_when(x1 == "Madrid, Comunidad de" ~ "Comunidad de Madrid",
                        x1 == "Castilla - La Mancha" ~ "Castilla-La Mancha", 
                        x1 == "Navarra, Comunidad Foral de" ~ "Comunidad Foral de Navarra",
                        x1 == "Comunitat Valenciana" ~ "Comunidad Valenciana",
                        x1 == "Balears, Illes" ~ 
                        "Islas Baleares",
                        x1 == "Canarias" ~ "Islas Canarias",
                        x1 == "Rioja, La" ~ "La Rioja",
                        x1 == "Asturias, Principado de" ~ "Principado de Asturias",
                        x1 == "Murcia, Región de" ~ "Región de Murcia",
                        TRUE ~ x1),
         ano_2024 = as.numeric(
           str_replace(ano_2024, ",", "."))) |> 
  filter(x1 != "TOTAL") 

spain_arope <-
  st_read("carto/ccaa_es.geojson", quiet = TRUE) |> 
  select(x1 = Name) |> 
  left_join(tasa_arope, by = "x1") |> 
  drop_na(ano_2024) |> 
  filter(x1 != "Islas Canarias")

ggplot(spain_arope) +
  geom_sf(aes(fill = ano_2024), color = "white") +
  scale_fill_viridis_c(option = "rocket", trans = "log", direction = -1, na.value = "gray90", name = "") +
  labs(title = "La pobreza, por comunidades autónomas",
       subtitle = "Tasa de riesgo de pobreza o exclusión social AROPE",
       caption = "Fuente: INE") +
  theme_minimal() +
  theme(axis.text = element_blank(), 
        panel.grid = element_blank(),
        title = element_text(size = 35),
        plot.subtitle = element_text(size = 30),
        legend.position = "top",
        legend.text = element_text(size = 25)) +
  guides(fill = guide_colorbar(barwidth = 30,
                               barheight = 2))
  

Mapas de coropletas

  • Ofrecen una visión general, pero dan poco detalle

  • Útiles para mostrar/investigar un patrón geográfico en los datos

  • Comparan una única variable que puede ser la diferencia entre dos valores

#| echo: false
#| fig.show: true
#| fig.width: 15  # Aumenta el ancho
#| fig.height: 20   # Aumenta la altura
#| fig.bg: transparent
#| label: paro-map

paro_es_23  <- 
  read_csv("data/tasa_paro_es_2023.csv")  |> 
  filter(ccaa == "C. Valenciana") |> 
  select(provincia = poligono, valor_mes) 

mapa_paro_cv <- 
  st_read("carto/provincias_valencia.geojson", quiet = TRUE) |> 
  select(provincia = Name) |> 
  st_transform(crs = 4326) |> 
  right_join(paro_es_23, by = "provincia")

ggplot(mapa_paro_cv) +
  geom_sf(aes(fill = valor_mes), color = "white") +
  scale_fill_gradient2(low = "#E0A458", mid = "#E0A45840" , high = "#C1440E", midpoint = 0, na.value = "grey") +
  labs(title = "El paro en la Comunidad Valenciana",
       subtitle = "Variación intermensual del paro registrado\nen septiembre de 2023",
       caption = "Fuente: Servicio Público de Empleo Estatal (SEPE)") +
  theme_minimal() +
  theme(axis.text = element_blank(), 
        panel.grid = element_blank(),
        title = element_text(size = 35),
        plot.subtitle = element_text(size = 30),
        legend.position = "top",
        legend.text = element_text(size = 25)) +
  guides(fill = guide_colorbar(barwidth = 30,
                               barheight = 2, title = ""))

Mapas de coropletas

  • Ofrecen una visión general, pero dan poco detalle

  • Útiles para mostrar/investigar un patrón geográfico en los datos

  • Comparan una única variable que puede ser la diferencia entre dos valores

  • Funcionan mejor con datos relativos ([Haz comparaciones justas])

#| echo: false
#| fig.show: true
#| fig.width: 15  # Aumenta el ancho
#| fig.height: 15   # Aumenta la altura
#| fig.bg: transparent
#| label: narco-map

delitos_narcotrafico <- 
  read_csv("data/delitos_narcotrafico_es_2021.csv") |> 
  janitor::clean_names() |> 
  select(territorio, tasa_100_000) |> 
  mutate(territorio = case_when(territorio == "Araba" ~ "Álava",
                                territorio == "Gipuzkoa" ~ "Guipúzcoa",
                                territorio == "Bizkaia" ~ "Vizcaya",
                                TRUE ~ territorio))

mapa_narcotrafico <-
  st_read("carto/provinces_es.geojson", quiet = TRUE) |> 
  select(territorio = Name) |> 
  left_join(delitos_narcotrafico, by = "territorio") |> 
  filter(!territorio %in% c("Santa Cruz de Tenerife",
                           "Las Palmas"))

ggplot(mapa_narcotrafico) +
  geom_sf(aes(fill = tasa_100_000), color = "white") +
  scale_fill_viridis_b(option = "rocket", trans = "log", direction = -1, na.value = "gray90", name = "",
                       label = scales::label_number(),
                       n.breaks = 8) +
  labs(title = "Delito de narcotráfico en 2021",
       caption = "Fuente: Portal Estadístico de Criminalidad del Ministerio del Interior") +
  theme_minimal() +
  theme(axis.text = element_blank(), 
        panel.grid = element_blank(),
        title = element_text(size = 35),
        plot.subtitle = element_text(size = 30),
        legend.position = "top",
        legend.title = element_text(size = 20, 
                                    face = "bold",),
        legend.text = element_text(size = 15)) +
  guides(fill = guide_colorbar(barwidth = 30,
                               barheight = 2, 
                               title = "Delitos por 100.000 habitantes",
                               title.position = "top"))

Añade información de referencia

  • Añade detalles al mapa que ayuden a los usuarios a interpretarlo.

  • Etiqueta ciudades importantes, calles, mares o ríos que aporten contexto a la historia.

Kenneth Field

Escalas en los mapas (I)

  • La escala de un mapa de coropletas funciona como los intervalos de los histogramas.

  • El número de pasos y su tamaño pueden alterar el mensaje de la visualización final.

Escalas en los mapas (II)

Los intervalos iguales aseguran pasos del mismo tamaño.

#| echo: false
#| fig.show: true
#| fig.width: 15  # Aumenta el ancho
#| fig.height: 7   # Aumenta la altura
#| fig.bg: transparent
#| label: galicia-map

renta_galicia <- 
  read_csv("data/renta_galicia.csv") |> 
  mutate(cod_mun = str_pad(cod_mun, width = 5, pad = 0))

mapa_galicia <- 
  st_read("carto/recintos_mun_pen/recintos_municipales_inspire_peninbal_etrs89.shp", quiet = TRUE) |> 
  filter(CODNUT2 == "ES11") |> 
  mutate(cod_mun = str_sub(NATCODE, 7, 11)) |> 
  select(cod_mun) |> 
  left_join(renta_galicia, by = "cod_mun")

mapa_galicia_renta_iguales <- 
  mapa_galicia |> 
  mutate(bines = case_when(between(Total, 7615, 9462.2) ~ "b1",
                           between(Total, 9462.2, 11309.4) ~ "b2",
                           between(Total, 11309.4, 13156.6) ~ "b3",
                           between(Total, 13156.6, 15003.8) ~ "b4",
                           between(Total, 15003.8, 16851) ~ "b5"))

#Valores de los breaks
breaks <- c(7615, 9462.2, 11309.4, 13156.6, 15003.8, 16851)

galicia_pasos_iguales_hist <-
ggplot(mapa_galicia_renta_iguales) +
  geom_histogram(aes(x = Total, fill = bines), 
                 bins = 99, 
                 show.legend = F) +
  scale_fill_manual(values = rev(MetBrewer::met.brewer("Greek", n = 5))) +
  labs(x = "", y = "Nº municipios",
       title = "Intervalos iguales de 1.847 €") +
  annotate("segment", x = 9462.2, 
                   y = 0, 
                   xend = 9462.2, 
                   yend = 20, 
               color = "black",
               size = 1,
               linetype = "dashed") +
  annotate("segment", x = 11309.4, 
                   y = 0, 
                   xend = 11309.4, 
                   yend = 20, 
               color = "black",
               size = 1,
               linetype = "dashed") +
  annotate("segment", x = 13156.6, 
                   y = 0, 
                   xend = 13156.6, 
                   yend = 20, 
               color = "black",
               size = 1,
               linetype = "dashed") +
  annotate("segment", x = 15003.8, 
                   y = 0, 
                   xend = 15003.8, 
                   yend = 20, 
               color = "black",
               size = 1,
               linetype = "dashed") +
  annotate("segment", x = 9462.2, 
                   y = 19.5, 
                   xend = 11309.4, 
                   yend = 19.5, 
               color = "black",
               size = 1,
               arrow = arrow(length = unit(0.4, "cm"))) +
  annotate("segment", x = 9462.2, 
                   y = 19.5, 
                   xend = 9462.2, 
                   yend = 19.5, 
               color = "black",
               size = 1,
               arrow = arrow(length = unit(0.4, "cm"))) +
  annotate("segment", x = 11309.4, 
                   y = 19.5, 
                   xend = 13156.6, 
                   yend = 19.5, 
               color = "black",
               size = 1,
               arrow = arrow(length = unit(0.4, "cm"))) +
  annotate("segment", x = 11309.4, 
                   y = 19.5, 
                   xend = 11309.4, 
                   yend = 19.5, 
               color = "black",
               size = 1,
               arrow = arrow(length = unit(0.4, "cm"))) +
  annotate("segment", x = 13156.6, 
                   y = 19.5, 
                   xend = 15003.8, 
                   yend = 19.5, 
               color = "black", 
               size = 1,
               arrow = arrow(length = unit(0.4, "cm"))) +
  annotate("segment", x = 13156.6, 
                   y = 19.5, 
                   xend = 13156.6, 
                   yend = 19.5, 
               color = "black",
               size = 1,
               arrow = arrow(length = unit(0.4, "cm"))) +
  theme_minimal() +
  theme(axis.title = element_text(size = 25),
        axis.text = element_text(size = 25),
        title = element_text(size = 30))

galicia_pasos_iguales_hist
#| echo: false
#| fig.show: true
#| fig.width: 15  # Aumenta el ancho
#| fig.height: 15   # Aumenta la altura
#| fig.bg: transparent
#| label: galicia2-map

# Crear un data frame con las coordenadas de las ciudades a destacar
ciudades_galicia <- tibble(
  nombre = c("A Coruña", "Lugo", "Ourense", "Pontevedra", 
             "Santiago\nde Compostela", "Vigo"),
  lat = c(43.3623, 43.0125, 42.3358, 42.4333, 42.8806, 42.2406),
  lon = c(-8.4115, -7.5550, -7.8639, -8.6444, -8.5456, -8.7207),
  desplazamiento = c(0.14, # A Coruña
                     0.12, # Lugo
                     0.14, # Ourense
                     0.14, # Pontevedra
                     0.14, # Santiago
                     0.12  # Vigo
                     ))

# Convertir el data frame en un objeto sf
ciudades_galicia_sf <- st_as_sf(ciudades_galicia, coords = c("lon", "lat"), crs = 4326)

galicia_pasos_iguales_map <-
ggplot(mapa_galicia_renta_iguales) +
  geom_sf(aes(fill = bines), color = "white") +
  scale_fill_manual(values = rev(MetBrewer::met.brewer("Greek", n = 5)), 
                    label = scales::label_number()(breaks[-1])) +
    # Puntos de las ciudades
  geom_sf(data = ciudades_galicia_sf, color = "white", size = 3) +
  geom_text(data = ciudades_galicia, aes(x = lon, y = lat, label = nombre, color = "black"), 
            nudge_x = 0.01,
            size = 8, fontface = "bold") + # Etiquetas
  geom_text(data = ciudades_galicia, aes(x = lon, y = lat, label = nombre, color = "white"), size = 8, fontface = "bold") + # Etiquetas
  scale_color_identity() +  # Usar los colores tal cual están en la variable
  labs(title = "Intervalos iguales",
       fill = "Renta neta media/persona (€)") +
  theme_minimal() +
  theme(axis.text = element_blank(), 
        axis.title = element_blank(),
        axis.ticks = element_blank(),
        panel.grid = element_blank(),
        title = element_text(size = 35),
        plot.subtitle = element_text(size = 30),
        legend.position = "top",
        legend.title = element_text(size = 30, face = "bold"),
        legend.text = element_text(size = 30)) 

galicia_pasos_iguales_map

Escalas en los mapas (III)

Los cuantiles reparten el mismo número de áreas del mapa (polígonos) en cada paso.

#| echo: false
#| fig.show: true
#| fig.width: 15  # Aumenta el ancho
#| fig.height: 7   # Aumenta la altura
#| fig.bg: transparent
#| label: galicia3-map

mapa_renta_galicia_cuantiles <- 
  mapa_galicia |> 
  mutate(bines = case_when(between(Total, 7615, 11064.6) ~ "b1", between(Total, 11064.6, 11572.2) ~ "b2", between(Total, 11572.2, 11977.4) ~ "b3", between(Total, 11977.4, 12713) ~ "b4", between(Total, 12713, 16851) ~ "b5"))

#Valores de los breaks
breaks <- c(7615, 11064.6, 11572.2, 11977.4, 12713, 16851)

galicia_cuantiles_hist <- 
ggplot(mapa_renta_galicia_cuantiles) +
  geom_histogram(aes(x = Total, fill = bines), 
                 bins = 99, 
                 show.legend = F) +
  scale_fill_manual(values = rev(MetBrewer::met.brewer("Greek", n = 5))) +
  labs(x = "", y = "Nº municipios",
       title = "Cada paso tiene asignado un número igual de municipios") +
  annotate("segment", x = 11064.6, 
                   y = 0, 
                   xend = 11064.6, 
                   yend = 20, 
               color = "black",
               size = 1,
               linetype = "dashed") +
  annotate("segment", x = 11572.2, 
                   y = 0, 
                   xend = 11572.2, 
                   yend = 20, 
               color = "black",
               size = 1,
               linetype = "dashed") +
  annotate("segment", x = 11977.4, 
                   y = 0, 
                   xend = 11977.4, 
                   yend = 20, 
               color = "black",
               size = 1,
               linetype = "dashed") +
  annotate("segment", x = 12713, 
                   y = 0, 
                   xend = 12713, 
                   yend = 20, 
               color = "black",
               size = 1,
               linetype = "dashed") +
  annotate("segment", x = 11064.6, 
                   y = 19.5, 
                   xend = 11572.2, 
                   yend = 19.5, 
               color = "black",
               size = 1,
               arrow = arrow(length = unit(0.4, "cm"))) +
  annotate("segment", x = 11064.6, 
                   y = 19.5, 
                   xend = 11064.6, 
                   yend = 19.5, 
               color = "black",
               size = 1,
               arrow = arrow(length = unit(0.4, "cm"))) +
  annotate("segment", x = 11572.2, 
                   y = 19.5, 
                   xend = 11977.4, 
                   yend = 19.5, 
               color = "black",
               size = 1,
               arrow = arrow(length = unit(0.4, "cm"))) +
  annotate("segment", x = 11572.2, 
                   y = 19.5, 
                   xend = 11572.2, 
                   yend = 19.5, 
               color = "black",
               size = 1,
               arrow = arrow(length = unit(0.4, "cm"))) +
  annotate("segment", x = 11977.4, 
                   y = 19.5, 
                   xend = 12713, 
                   yend = 19.5, 
               color = "black", 
               size = 1,
               arrow = arrow(length = unit(0.4, "cm"))) +
  annotate("segment", x = 11977.4, 
                   y = 19.5, 
                   xend = 11977.4, 
                   yend = 19.5, 
               color = "black",
               size = 1,
               arrow = arrow(length = unit(0.4, "cm"))) +
  theme_minimal() +
  theme(axis.title = element_text(size = 25),
        axis.text = element_text(size = 25),
        title = element_text(size = 30))

galicia_cuantiles_hist
#| echo: false
#| fig.show: true
#| fig.width: 15  # Aumenta el ancho
#| fig.height: 15   # Aumenta la altura
#| fig.bg: transparent
#| label: galicia4-map

galicia_cuantiles_map <-
ggplot(mapa_renta_galicia_cuantiles) +
  geom_sf(aes(fill = bines), color = "white") +
  scale_fill_manual(values = rev(MetBrewer::met.brewer("Greek", n = 5)), 
                    label = scales::label_number()(breaks[-1])) +
    # Puntos de las ciudades
  geom_sf(data = ciudades_galicia_sf, color = "white", size = 3) +
  geom_text(data = ciudades_galicia, aes(x = lon, y = lat, label = nombre, color = "black"), 
            nudge_x = 0.01,
            size = 8, fontface = "bold") + # Etiquetas
  geom_text(data = ciudades_galicia, aes(x = lon, y = lat, label = nombre, color = "white"), size = 8, fontface = "bold") + # Etiquetas
  scale_color_identity() +  # Usar los colores tal cual están en la variable
  labs(title = "Cuantiles (recuento igual)",
       fill = "Renta neta media/persona (€)") +
  theme_minimal() +
  theme(axis.text = element_blank(), 
        axis.title = element_blank(),
        axis.ticks = element_blank(),
        panel.grid = element_blank(),
        title = element_text(size = 35),
        plot.subtitle = element_text(size = 30),
        legend.position = "top",
        legend.title = element_text(size = 30, face = "bold"),
        legend.text = element_text(size = 30)) 

galicia_cuantiles_map

Escalas en los mapas (IV)

#| echo: false
#| fig.show: true
#| fig.width: 15  # Aumenta el ancho
#| fig.height: 15   # Aumenta la altura
#| fig.bg: transparent
#| label: galicia5-map

galicia_pasos_iguales_map
#| echo: false
#| fig.show: true
#| fig.width: 15  # Aumenta el ancho
#| fig.height: 7   # Aumenta la altura
#| fig.bg: transparent
#| label: galicia6-map

galicia_pasos_iguales_hist
#| echo: false
#| fig.show: true
#| fig.width: 15  # Aumenta el ancho
#| fig.height: 15   # Aumenta la altura
#| fig.bg: transparent
#| label: galicia7-map

galicia_cuantiles_map
#| echo: false
#| fig.show: true
#| fig.width: 15  # Aumenta el ancho
#| fig.height: 7   # Aumenta la altura
#| fig.bg: transparent
#| label: galicia8-map

galicia_cuantiles_hist

Escalas en los mapas (V)

Los intervalos naturales o Jenks son un método diseñado por el cartógrafo George Jenks para optimizar la distribución de los datos en pasos teniendo en cuenta las agrupaciones y los patrones de la serie.

#| echo: false
#| fig.show: true
#| fig.width: 15  # Aumenta el ancho
#| fig.height: 7   # Aumenta la altura
#| fig.bg: transparent
#| label: galicia9-map

mapa_renta_galicia_jenks <- 
  mapa_galicia |> 
  mutate(bines = case_when(between(Total, 7615, 10634) ~ "b1", between(Total, 10634, 11548) ~ "b2", between(Total, 11548, 12523) ~ "b3", between(Total, 12523, 14313) ~ "b4", between(Total, 14313, 16851) ~ "b5"))

#Valores de los breaks
breaks <- c(7615, 10634, 11548, 12523, 14313, 16851)

galicia_jenks_hist <- 
ggplot(mapa_renta_galicia_jenks) +
  geom_histogram(aes(x = Total, fill = bines), 
                 bins = 99, 
                 show.legend = F) +
  scale_fill_manual(values = rev(MetBrewer::met.brewer("Greek", n = 5))) +
  labs(x = "", y = "Nº municipios",
       title = "Pasos optimizados según la distribución de los datos") +
  annotate("segment", x = 10634, 
                   y = 0, 
                   xend = 10634, 
                   yend = 20, 
               color = "black",
               size = 1,
               linetype = "dashed") +
  annotate("segment", x = 11548, 
                   y = 0, 
                   xend = 11548, 
                   yend = 20, 
               color = "black",
               size = 1,
               linetype = "dashed") +
  annotate("segment", x = 12523, 
                   y = 0, 
                   xend = 12523, 
                   yend = 20, 
               color = "black",
               size = 1,
               linetype = "dashed") +
  annotate("segment", x = 14313, 
                   y = 0, 
                   xend = 14313, 
                   yend = 20, 
               color = "black",
               size = 1,
               linetype = "dashed") +
  annotate("segment", x = 10634, 
                   y = 19.5, 
                   xend = 11548, 
                   yend = 19.5, 
               color = "black",
               size = 1,
               arrow = arrow(length = unit(0.4, "cm"))) +
  annotate("segment", x = 10634, 
                   y = 19.5, 
                   xend = 10634, 
                   yend = 19.5, 
               color = "black",
               size = 1,
               arrow = arrow(length = unit(0.4, "cm"))) +
  annotate("segment", x = 11548, 
                   y = 19.5, 
                   xend = 12523, 
                   yend = 19.5, 
               color = "black",
               size = 1,
               arrow = arrow(length = unit(0.4, "cm"))) +
  annotate("segment", x = 11548, 
                   y = 19.5, 
                   xend = 11548, 
                   yend = 19.5, 
               color = "black",
               size = 1,
               arrow = arrow(length = unit(0.4, "cm"))) +
  annotate("segment", x = 12523, 
                   y = 19.5, 
                   xend = 14313, 
                   yend = 19.5, 
               color = "black", 
               size = 1,
               arrow = arrow(length = unit(0.4, "cm"))) +
  annotate("segment", x = 12523, 
                   y = 19.5, 
                   xend = 12523, 
                   yend = 19.5, 
               color = "black",
               size = 1,
               arrow = arrow(length = unit(0.4, "cm"))) +
  theme_minimal() +
  theme(axis.title = element_text(size = 25),
        axis.text = element_text(size = 25),
        title = element_text(size = 30))

galicia_jenks_hist
#| echo: false
#| fig.show: true
#| fig.width: 15  # Aumenta el ancho
#| fig.height: 15   # Aumenta la altura
#| fig.bg: transparent
#| label: galicia10-map

galicia_jenks_map <-
ggplot(mapa_renta_galicia_jenks) +
  geom_sf(aes(fill = bines), color = "white") +
  scale_fill_manual(values = rev(MetBrewer::met.brewer("Greek", n = 5)), 
                    label = scales::label_number()(breaks[-1])) +
    # Puntos de las ciudades
  geom_sf(data = ciudades_galicia_sf, color = "white", size = 3) +
  geom_text(data = ciudades_galicia, aes(x = lon, y = lat, label = nombre, color = "black"), 
            nudge_x = 0.01,
            size = 8, fontface = "bold") + # Etiquetas
  geom_text(data = ciudades_galicia, aes(x = lon, y = lat, label = nombre, color = "white"), size = 8, fontface = "bold") + # Etiquetas
  scale_color_identity() +  # Usar los colores tal cual están en la variable
  labs(title = "Intervalos naturales (Jenks)",
       fill = "Renta neta media/persona (€)") +
  theme_minimal() +
  theme(axis.text = element_blank(), 
        axis.title = element_blank(),
        axis.ticks = element_blank(),
        panel.grid = element_blank(),
        title = element_text(size = 35),
        plot.subtitle = element_text(size = 30),
        legend.position = "top",
        legend.title = element_text(size = 30, face = "bold"),
        legend.text = element_text(size = 30)) 

galicia_jenks_map

Escalas en los mapas (VI)

#| echo: false
#| fig.show: true
#| fig.width: 15  # Aumenta el ancho
#| fig.height: 15   # Aumenta la altura
#| fig.bg: transparent
#| label: galicia11-map

galicia_educacion_superior <- 
  read_csv("data/educacion_superior_galicia.csv",
           col_types = "cccnccn")  |> 
  rename(cod_mun = cod_ine) |> 
  mutate(cod_mun = str_pad(cod_mun, pad = 0, 5),
         por_educacion_sup = str_pad(por_educacion_sup,
                                     pad = 0, 
                                     side = "right", 4),
         por_educacion_sup = as.numeric(por_educacion_sup)/100) 

mapa_galicia_educacion <- 
  mapa_galicia |> 
  left_join(galicia_educacion_superior, by = "cod_mun")

mapa_galicia_educacion_iguales <- 
  mapa_galicia_educacion |> 
  mutate(bines = case_when(por_educacion_sup < 14.58 ~ "b1",
                           between(por_educacion_sup, 
                                   14.58, 20.97) ~ "b2",
                           between(por_educacion_sup, 
                                   20.97, 27.37) ~ "b3", 
                           between(por_educacion_sup, 
                                   27.37, 33.76) ~ "b4",
                           por_educacion_sup >= 33.76 ~ "b5"))

#Valores de los breaks
breaks <- c(0, 14.58, 20.97, 27.37, 33.76, 99.60)

ggplot(mapa_galicia_educacion_iguales) +
  geom_sf(aes(fill = bines), color = "white") +
  scale_fill_manual(values = rev(MetBrewer::met.brewer("Greek", n = 5)), 
                    label = scales::label_number()(breaks[-1])) +
    # Puntos de las ciudades
  geom_sf(data = ciudades_galicia_sf, color = "white", size = 3) +
  geom_text(data = ciudades_galicia, aes(x = lon, y = lat, label = nombre, color = "black"), 
            nudge_x = 0.01,
            size = 8, fontface = "bold") + # Etiquetas
  geom_text(data = ciudades_galicia, aes(x = lon, y = lat, label = nombre, color = "white"), size = 8, fontface = "bold") + # Etiquetas
  scale_color_identity() +  # Usar los colores tal cual están en la variable
  labs(title = "Intervalos iguales",
       fill = "% pob. educación superior") +
  theme_minimal() +
  theme(axis.text = element_blank(), 
        axis.title = element_blank(),
        axis.ticks = element_blank(),
        panel.grid = element_blank(),
        title = element_text(size = 35),
        plot.subtitle = element_text(size = 30),
        legend.position = "top",
        legend.title = element_text(size = 30, face = "bold"),
        legend.text = element_text(size = 30)) 
#| echo: false
#| fig.show: true
#| fig.width: 15  # Aumenta el ancho
#| fig.height: 15   # Aumenta la altura
#| fig.bg: transparent
#| label: galicia12-map

mapa_galicia_educacion_cuantiles <- 
  mapa_galicia_educacion |> 
  mutate(bines = case_when(por_educacion_sup < 14.24 ~ "b1",
                           between(por_educacion_sup, 
                                   14.24, 16.78) ~ "b2",
                           between(por_educacion_sup, 
                                   16.78, 19.01) ~ "b3", 
                           between(por_educacion_sup, 
                                   19.01, 22.2) ~ "b4",
                           por_educacion_sup >= 22.2 ~ "b5"))

#Valores de los breaks
breaks <- c(0, 14.24, 16.78, 19.01, 22.2, 99.60)

ggplot(mapa_galicia_educacion_cuantiles) +
  geom_sf(aes(fill = bines), color = "white") +
  scale_fill_manual(values = rev(MetBrewer::met.brewer("Greek", n = 5)), 
                    label = scales::label_number()(breaks[-1])) +
    # Puntos de las ciudades
  geom_sf(data = ciudades_galicia_sf, color = "white", size = 3) +
  geom_text(data = ciudades_galicia, aes(x = lon, y = lat, label = nombre, color = "black"), 
            nudge_x = 0.01,
            size = 8, fontface = "bold") + # Etiquetas
  geom_text(data = ciudades_galicia, aes(x = lon, y = lat, label = nombre, color = "white"), size = 8, fontface = "bold") + # Etiquetas
  scale_color_identity() +  # Usar los colores tal cual están en la variable
  labs(title = "Cuantiles (recuento igual)",
       fill = "% pob. educación superior") +
  theme_minimal() +
  theme(axis.text = element_blank(), 
        axis.title = element_blank(),
        axis.ticks = element_blank(),
        panel.grid = element_blank(),
        title = element_text(size = 35),
        plot.subtitle = element_text(size = 30),
        legend.position = "top",
        legend.title = element_text(size = 30, face = "bold"),
        legend.text = element_text(size = 30)) 
#| echo: false
#| fig.show: true
#| fig.width: 15  # Aumenta el ancho
#| fig.height: 15   # Aumenta la altura
#| fig.bg: transparent
#| label: galicia13-map

mapa_galicia_educacion_jenks <- 
  mapa_galicia_educacion |> 
  mutate(bines = case_when(por_educacion_sup < 14.34 ~ "b1",
                           between(por_educacion_sup, 
                                   14.34, 17.51) ~ "b2",
                           between(por_educacion_sup, 
                                   17.51, 21.44) ~ "b3", 
                           between(por_educacion_sup, 
                                   21.44, 28.51) ~ "b4",
                           por_educacion_sup >= 28.51 ~ "b5"))

#Valores de los breaks
breaks <- c(0, 14.34, 17.51, 21.44, 28.51, 99.60)

ggplot(mapa_galicia_educacion_jenks) +
  geom_sf(aes(fill = bines), color = "white") +
  scale_fill_manual(values = rev(MetBrewer::met.brewer("Greek", n = 5)), 
                    label = scales::label_number()(breaks[-1])) +
    # Puntos de las ciudades
  geom_sf(data = ciudades_galicia_sf, color = "white", size = 3) +
  geom_text(data = ciudades_galicia, aes(x = lon, y = lat, label = nombre, color = "black"), 
            nudge_x = 0.01,
            size = 8, fontface = "bold") + # Etiquetas
  geom_text(data = ciudades_galicia, aes(x = lon, y = lat, label = nombre, color = "white"), size = 8, fontface = "bold") + # Etiquetas
  scale_color_identity() +  # Usar los colores tal cual están en la variable
  labs(title = "Intervalos naturales (Jenks)",
       fill = "% pob. educación superior") +
  theme_minimal() +
  theme(axis.text = element_blank(), 
        axis.title = element_blank(),
        axis.ticks = element_blank(),
        panel.grid = element_blank(),
        title = element_text(size = 35),
        plot.subtitle = element_text(size = 30),
        legend.position = "top",
        legend.title = element_text(size = 30, face = "bold"),
        legend.text = element_text(size = 30)) 

¿Cuál es la opción correcta?

  • Todas. La pregunta correcta es: ¿Qué quieres contar y qué técnica se adapta mejor a la distribución de tus datos?

  • Como norma general…

  • Jenks, cuando quieres ofrecer una foto fija sin hacer comparaciones.

  • Cuantiles o intervalos iguales, cuando quieres hacer comparaciones entre mapas, ya que facilitas la búsqueda de patrones al dejar el mismo número de áreas o valores similares en cada intervalo.

¿Cuántos pasos debe tener la escala?

  • Si eliges pocos pasos …corres el riesgo de generalizar demasiado.

  • Si eliges muchos pasos …puedes estar complicando la comparación entre áreas.

Tip

Entre 5-7 clases Es un buen equilibrio, teniendo en cuenta los límites de la percepción visual.

Claves

  • 🍋 Aprovecha lo que tienes

  • 🧠 Entiende los datos

  • ✅ ✅ Comprueba y vuelve a comprobar

  • 📖 Cuenta una historia

  • 🔍 Pregúntale a ChatGPT (o a Google)

¡Gracias!

Bibliografía (I)

Bibliografía (II)

Bibliografía (III)