
Introducción al periodismo de datos ✅
Presentación periodística de datos, hechos y cifras
Narrativas visuales
Herramientas del periodista de datos
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”.
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)
El euribor está en el 4,074%
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

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.

Xaquín Veira González






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


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


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.
| País | Nº tarjetas de crédito (millones) |
|---|---|
| A | 100 |
| B | 300 |
| C | 400 |
| País | Nº tarjetas de crédito (millones) |
|---|---|
| A | 100 |
| B | 300 |
| C | 400 |
| 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 |
| 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 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.


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




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






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


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
Hay algunas excepciones:



Una leyenda separada de las líneas obliga a trabajar más al espectador
Nunca incluyas anotaciones largas y utiliza solo las necesarias

Las etiquetas junto a las líneas permiten una identificación rápida y directa
Las anotaciones han de ser claras y concisas

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
![]() |
![]() |
![]() |
| 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 |
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

¿Cómo mejoramos este gráfico?

¿Cómo mejoramos este gráfico?

¿Cómo mejoramos este gráfico?
Ordenamos de mayor a menor, con el grupo más numeroso pegado al eje.
Agrupo las categorías menos importantes en “Otros”.

¿Cómo mejoramos este gráfico?
Ordenamos de mayor a menor, con el grupo más numeroso pegado al eje.
Agrupo las categorías menos importantes en “Otros”.
Aplicamos una paleta de colores más limpia.

¿Cómo mejoramos este gráfico?
Ordenamos de mayor a menor, con el grupo más numeroso pegado al eje.
Agrupo las categorías menos importantes en “Otros”.
Aplicamos una paleta de colores más limpia.
Calculamos porcentajes para poder comparar.

¿Cómo mejoramos este gráfico?
Ordenamos de mayor a menor, con el grupo más numeroso pegado al eje.
Agrupo las categorías menos importantes en “Otros”.
Aplicamos una paleta de colores más limpia.
Calculamos porcentajes para poder comparar.
Destacamos una variable y reordenamos.

¿Cómo mejoramos este gráfico?
Ordenamos de mayor a menor, con el grupo más numeroso pegado al eje.
Agrupo las categorías menos importantes en “Otros”.
Aplicamos una paleta de colores más limpia.
Calculamos porcentajes para poder comparar.
Destacamos una variable y reordenamos.
Colocamos la leyenda junto a las barras.
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
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

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.


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
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

No deformes los pictogramas para transformarlos en barras/columnas. El tamaño debe ser proporcional en cuanto al área.
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.
Si los datos que vas a comparar están muy juntos, no uses pictogramas.
Una buena elección para mostrar la diferencia entre dos variables
Además de una comparación en horizontal, permite comparar en vertical
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
Max Roser
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

Barras divergentes

Flechas

Útiles para mostrar datos agrupados en intervalos
Muestran de un vistazo la evolución de una serie histórica
Warning
Comparados con un gráfico de líneas, los heatmaps hacen más difícil cuantificar cada dato por separado
Eficaces para comparar magnitudes en periodos de tiempo concretos
Muy útiles para datos de desastres naturales
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.

🍋 Aprovecha lo que tienes
🧠 Entiende los datos
✅ ✅ Comprueba y vuelve a comprobar
📖 Cuenta una historia
🔍 Pregúntale a ChatGPT (o a Google)
#| 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)Introducción al periodismo de datos ✅
Presentación periodística de datos, hechos y cifras ✅
Narrativas visuales
Herramientas del periodista de 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.
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
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.
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…
Realidad virtual, realidad aumentada y 3D
Narrativa cohesiva de eventos a través del tiempo en la que el usuario avanza mediante el scroll.
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
Tres páginas del The South China Morning Post
Población en territorios ocupados por religión (The Economist)

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
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 ⬤/⬤.
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.
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.
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.
Geo Awesomeness
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
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…).
Fuentes de datos cartográficos:
⛏️ Google (Universidades, organismos internacionales, investigadores…)
El formato importa
Mapas coropléticos 
Mapas de símbolos 
Localizadores 

#| 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))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.
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))
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 = ""))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 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
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.
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_mapLos 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_mapLos 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#| 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)) 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.
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.
🍋 Aprovecha lo que tienes
🧠 Entiende los datos
✅ ✅ Comprueba y vuelve a comprobar
📖 Cuenta una historia
🔍 Pregúntale a ChatGPT (o a Google)
10 ways to use fewer colors in your data visualizations, Lisa Charlotte Muth, Datawrapper Blog
An alternative to pink & blue: Colors for gender data, Lisa Charlotte Muth, Datawrapper
Area chart, Datawrapper
Cartography & Map Design. How to Make a Successful Map, Patrick Jankanish, URISA
Guide to Information Graphics. The Dos & Don’ts of Presenting Data, Facts, and Figures, Dona M. Wong, The Wall Street Journal
How Charts Work: Understand and explain data with confidence, Alan Smith, FT Publishing
How to create a symbol map, Datawrapper Academy
How to pick more beautiful colors for your data visualizations, Lisa Charlotte Muth, Datawrapper
La hora de la infografía. Por qué estalló el periodismo visual con el Covid-19 y cómo crean los infografistas las historias, Javier Pastoriza Portela y Roberta Barbán Franceschi, UNIR
Take Care of your Choropleth Maps, Gregor Aisch, vis4.net
What to consider when choosing colors for data visualization, Lisa Charlotte Muth, Datawrapper
What to consider when creating choropleth maps, Datawrapper Academy
What to consider when creating line charts, Lisa Charlotte Muth, Datawrapper Academy
What to consider when creating pie charts, Datawrapper Academy
What to consider when creating stacked column charts, Datawrapper Academy
What to consider when visualizing data for colorblind readers, Lisa Charlotte Muth, Datawrapper
When Maps Shouldn’t Be Maps, Matthew Ericson
When to use quantitative and when to use qualitative color scales, Lisa Charlotte Muth, Datawrapper
When to use sequential and when to use diverging color scales, Lisa Charlotte Muth, Datawrapper