Diagramas de Sankey con R y Python: Visualización efectiva de flujos y relaciones.

Nicolás Urrego
15 min readAug 31, 2023

En la actualidad, donde los datos se convierten en una fuente inagotable de información, el desafío fundamental radica en comprender y comunicar de manera efectiva los patrones, flujos y relaciones dentro de esta maraña de datos. En este proceso, la visualización de datos emerge como una herramienta esencial, transformando datos complejos en representaciones visuales comprensibles y de gran significado. Entre la diversidad de herramientas de visualización, destaca el potente diagrama de Sankey, una forma única y eficaz de representar flujos y relaciones en diversos contextos.

Fuente: DataVizProject

El diagrama de Sankey, una herramienta visual, capta la esencia de los flujos y transiciones entre los elementos de un sistema. Su diseño singular permite ilustrar conexiones intrincadas, proporcionando una comprensión intuitiva de cómo las cantidades se trasladan de un estado a otro.

El término “Sankey” proviene de Matthew Henry Phineas Riall Sankey, un capitán del Cuerpo de Ingenieros Reales británico del siglo XIX, quien ideó esta forma de representación para visualizar flujos de energía en máquinas de vapor. No obstante, la historia del diagrama de Sankey se extiende más allá de su nombre. A lo largo de los años, esta metodología ha evolucionado y encontrado aplicaciones en una diversidad de campos.

Desde sus orígenes en la ingeniería industrial hasta su adaptación en la visualización de datos en áreas como la ciencia ambiental, la economía y la gestión empresarial, el diagrama de Sankey ha demostrado ser una herramienta versátil y valiosa para comunicar patrones de flujo y transiciones. Su habilidad para simplificar representaciones complejas lo convierte en un recurso preciado para profesionales en búsqueda de entender y comunicar las relaciones entre diversos elementos.

Este artículo sumerge a fondo en el diagrama de Sankey, desde sus fundamentos hasta su aplicación en análisis de datos y toma de decisiones. Mediante ejemplos prácticos y herramientas populares, descubriremos cómo esta herramienta puede iluminar los flujos y relaciones subyacentes en datos complejos, asistiendo a profesionales a tomar decisiones informadas y comunicar ideas de manera efectiva.

Tabla de contenidos:

  1. Estructura del Diagrama de Sankey
  2. Aplicaciones en diversos sectores
  3. Creación de un Diagrama de Sankey: Paso a paso
  4. Consideraciones sobre los datos y mejores prácticas
  5. Creación de diagramas de Sankey con R y Python
  6. Personalización y optimización de diagramas de Sankey
  7. Exportación e Interactividad

Estructura del Diagrama de Sankey

En su forma más básica, un diagrama de Sankey consiste en una serie de nodos interconectados por flujos que representan las cantidades que se mueven de un nodo a otro. Los nodos son los puntos en el diagrama donde se inician o terminan los flujos, mientras que los flujos son las conexiones entre los nodos que representan los movimientos de cantidades entre ellos. La estructura y el diseño del diagrama se organizan de manera que el ancho de los flujos sea proporcional a la cantidad que representan, lo que facilita la comparación visual.

Componentes clave del Diagrama de Sankey

  1. Nodos: Los nodos son las entidades en el diagrama que representan las categorías o estados específicos. Pueden ser puntos de inicio o finalización de los flujos. Cada nodo se etiqueta con el nombre de la categoría o estado que representa.
  2. Flujos: Los flujos son las conexiones entre los nodos que representan el movimiento de cantidades de una categoría a otra. Los flujos pueden tener orientaciones diferentes según si representan flujos entrantes o salientes.
  3. Orientaciones: Los flujos pueden tener orientaciones específicas que indican la dirección del movimiento de cantidades entre los nodos. Las orientaciones más comunes son desde la izquierda hacia la derecha, desde y hacia arriba o desde y hacia abajo.

Ejemplos visuales

Para comprender mejor cómo funciona un diagrama de Sankey, consideremos un ejemplo. Supongamos que deseamos visualizar el flujo de migraciones en 2013. En este caso, los nodos podrían representar diferentes regiones (países) y el origen de las migraciones, dentro o fuera de la UE. Los flujos representarían la cantidad de personas que se han movido a una región, y las orientaciones indicarían la dirección de estos flujos.

Creador: Giovanni Rabuffetti

Otro ejemplo podría ser el análisis de los gastos que realiza cada departamento en diferentes recursos, podemos saber qué recursos son y en que magnitud se realiza el gasto.

Creador: Shravan

Aplicaciones en diversos sectores

El diagrama de Sankey, con su capacidad para visualizar flujos y relaciones complejas, encuentra aplicaciones en una variedad de sectores y disciplinas. Su versatilidad lo convierte en una herramienta valiosa para comprender patrones y optimizar procesos en diferentes áreas:

  1. Gestión de la cadena de suministro: En el ámbito de la logística y la cadena de suministro, el diagrama de Sankey se utiliza para mapear y analizar el flujo de materiales a lo largo de toda la cadena. Permite identificar cuellos de botella, ineficiencias y oportunidades de mejora en la distribución y el manejo de recursos.
  2. Investigación científica y medioambiental: En la investigación científica y el estudio del medio ambiente, el diagrama de Sankey se utiliza para visualizar y cuantificar el flujo de energía y recursos en sistemas complejos. Por ejemplo, en la ecología, puede representar la transferencia de nutrientes en una red alimentaria o la distribución de carbono en un ecosistema.
  3. Análisis de datos empresariales: En el ámbito empresarial, el diagrama de Sankey es una herramienta poderosa para explorar y comunicar datos complejos. Se utiliza para trazar flujos financieros, analizar patrones de compra y ventas, y comprender la estructura de costos en diferentes departamentos o proyectos.
  4. Diseño de procesos y plantas industriales: En la ingeniería y el diseño de plantas industriales, el diagrama de Sankey se emplea para planificar y optimizar la distribución de recursos y energía. Ayuda a identificar cómo se pueden utilizar de manera más eficiente los insumos y cómo se pueden minimizar las pérdidas.
  5. Visualización de datos energéticos: En el sector de la energía, el diagrama de Sankey es una herramienta clave para mostrar el flujo y la distribución de distintas fuentes de energía en sistemas complejos. Puede utilizarse para comprender la mezcla de energías renovables y no renovables en la producción de electricidad.
  6. Planificación urbana y de transporte: En la planificación urbana, el diagrama de Sankey puede ser utilizado para visualizar los flujos de tráfico y la movilidad en una ciudad. Esto ayuda a identificar los patrones de transporte, las áreas congestionadas y las oportunidades de mejora en la infraestructura vial.
  7. Educación y comunicación: Más allá de los sectores específicos, el diagrama de Sankey se convierte en una herramienta educativa poderosa. Puede utilizarse para simplificar conceptos complejos y comunicar ideas de manera efectiva, ya que su estructura visual facilita la comprensión de relaciones y flujos.

En resumen, el diagrama de Sankey es una herramienta multidisciplinaria que encuentra aplicaciones en una amplia gama de sectores y áreas. Su capacidad para representar flujos, patrones y relaciones complejas lo convierte en una herramienta esencial para la toma de decisiones informadas y la comunicación efectiva de datos.

Creación de un Diagrama de Sankey: Paso a paso

A continuación, te guiaré a través de los pasos fundamentales para crear tu propio diagrama de Sankey:

  1. Recopila tus datos: Reúne los datos que deseas visualizar en tu diagrama. Asegúrate de tener información clara sobre las conexiones o flujos entre diferentes elementos. Estos datos son esenciales para construir un diagrama preciso.
  2. Define tus nodos: Identifica los nodos o elementos en tu conjunto de datos. Estos nodos representarán las fuentes, destinos o estados en tu diagrama. Cada nodo debe tener un nombre o etiqueta única.
  3. Crea tus conexiones: Establece las conexiones entre los nodos. Determina cómo fluye la información, los recursos o las cantidades de un nodo a otro. Asigna valores numéricos a estas conexiones para representar la magnitud de los flujos.
  4. Selecciona una herramienta: Elige una herramienta o biblioteca de visualización de datos que te permita crear diagramas de Sankey. Algunas opciones populares incluyen D3.js en JavaScript, networkD3 en R y Plotly en Python.
  5. Prepara tus datos: Formatea tus datos de acuerdo con los requisitos de la herramienta que seleccionaste. A menudo, necesitarás estructurar tus datos en un marco de datos que contenga información sobre las conexiones y los nodos.
  6. Personaliza tu diagrama: Añade detalles visuales y personalización a tu diagrama. Puedes ajustar los colores, las etiquetas, el espaciado y otros aspectos para que se adapten a tus necesidades y mejoren la legibilidad.
  7. Visualiza tu diagrama: Utiliza la herramienta seleccionada para crear el diagrama de Sankey. Asegúrate de que refleje fielmente los flujos y relaciones que deseas comunicar.
  8. Interactúa con tu diagrama: Si estás utilizando una herramienta interactiva, explora las funcionalidades disponibles. Algunas herramientas permiten a los usuarios interactuar con el diagrama, lo que puede proporcionar una comprensión más profunda de los datos.
  9. Comunica tus resultados: Finalmente, comparte tu diagrama de Sankey con tu audiencia. Explica las conclusiones que se pueden extraer de la visualización y cómo esto puede ser útil en la toma de decisiones o la comunicación de información compleja.

¡Sigue estos pasos y estarás en camino para crear diagramas de Sankey efectivos y significativos!

Consideraciones sobre los datos y mejores prácticas

Los datos en escalas diferentes pueden ser adecuados para un diagrama de Sankey, dependiendo del contexto y del propósito de la visualización. Sin embargo, es importante tener en cuenta algunas consideraciones:

  1. Proporcionalidad: En un diagrama de Sankey, el ancho de las flechas o las conexiones entre nodos suele representar la magnitud de los flujos. Si los datos están en escalas muy diferentes, es posible que algunas conexiones sean casi invisibles o demasiado pequeñas para percibirlas. Esto puede hacer que la visualización sea ineficaz para comunicar ciertas relaciones.
  2. Normalización: Una forma de abordar este problema es normalizar los datos. La normalización implica escalar todos los datos para que estén en la misma escala o unidad. Esto puede ayudar a que los flujos sean más comparables y visibles en el diagrama.
  3. Destacar flujos relevantes: Otra opción es destacar los flujos más importantes o significativos en la visualización. Puedes resaltar ciertas conexiones o nodos para que la audiencia se centre en los aspectos clave de los datos, mientras que las conexiones menos relevantes se muestran de manera más tenue.
  4. Información contextual: A veces, es útil mostrar datos en diferentes escalas si refleja la realidad o proporciona información valiosa. Por ejemplo, en un diagrama de Sankey sobre fuentes de energía, puede ser importante mostrar que una pequeña cantidad de energía proviene de una fuente minoritaria.
  5. Leyendas y etiquetas: Asegúrate de incluir leyendas y etiquetas claras en tu diagrama para que los espectadores comprendan las escalas y los valores representados. Esto ayuda a evitar malentendidos y garantiza que la visualización sea informativa.

En resumen, si los datos están en escalas diferentes, es fundamental considerar cómo esta disparidad afectará la comprensión de la visualización. La normalización, el resaltado y la explicación adecuada pueden ayudar a superar los desafíos relacionados con escalas dispares y garantizar que tu diagrama de Sankey sea efectivo.

Creación de diagramas de Sankey con R y Python

En la actualidad, varias bibliotecas y herramientas de programación ofrecen la posibilidad de crear diagramas de Sankey en una variedad de lenguajes, como R y Python. A continuación, exploraremos cómo utilizar algunas de estas herramientas para generar diagramas de Sankey interactivos y estáticos:

Uso de la biblioteca networkD3 en R

La biblioteca networkD3 en R es una excelente opción para crear diagramas de Sankey interactivos. Proporciona la capacidad de visualizar y explorar flujos de datos de manera dinámica. Aquí hay un ejemplo de cómo construir un diagrama de Sankey interactivo utilizando esta biblioteca:

# Instalar y cargar la biblioteca networkD3
install.packages("networkD3")
library(networkD3)
library(dplyr)

# Crear el marco de datos de conexiones
links <- data.frame(
source = c("Fuente A", "Fuente A", "Fuente B", "Fuente C"),
target = c("Destino X", "Destino Y", "Destino Z", "Destino Z"),
value = c(20, 30, 50, 10)
)

# Crear el marco de datos de nodos
nodes <- data.frame(
name=c(as.character(links$source), as.character(links$target)) %>% unique()
)

# Crear los ID de nodos para la conexión
links$IDsource <- match(links$source, nodes$name) - 1
links$IDtarget <- match(links$target, nodes$name) - 1

# Crear el diagrama de Sankey
p <- sankeyNetwork(
Links = links,
Nodes = nodes,
Source = "IDsource",
Target = "IDtarget",
Value = "value",
NodeID = "name",
sinksRight = FALSE
)

# Mostrar el diagrama de Sankey
p

Utilización de Plotly en Python:

La biblioteca Plotly en Python permite crear diagramas de Sankey con interactividad y personalización. Aquí tienes un ejemplo de cómo generar un diagrama de Sankey interactivo utilizando Plotly, cuyos datos se obtienen de un archivo JSON:

import json
import plotly.graph_objects as go

# Importar el archivo JSON
with open("sankey_energy.json") as f:
data = json.load(f)

# Crear los nodos
nodes = {node: dict(label=node) for node in data["sources"] + data["sinks"]}

# Crear los flujos
links = [{
"source": data["sources"].index(flow["source"]),
"target": len(data["sources"]) + data["sinks"].index(flow["sink"]),
"value": flow["value"],
} for flow in data["flows"]]

# Crear el diagrama de Sankey
fig = go.Figure(go.Sankey(
node=dict(
pad=20,
thickness=20,
line=dict(color="black", width=0.5),
label=list(nodes.keys()),
),
link=dict(
source=[link["source"] for link in links],
target=[link["target"] for link in links],
value=[link["value"] for link in links],
)
))

# Actualizar el diseño del diagrama
fig.update_layout(
title_text=data["title"],
font_size=10,
autosize=False,
width=1000,
height=500,
)

# Mostrar el diagrama
fig.show()

El archivo JSON tiene la siguiente estructura

{
"title": "Diagrama de Sankey de una planta de energía",
"sources": ["Combustible", "Energía solar", "Energía eólica"],
"sinks": ["Electricidad", "Calor", "Gases de efecto invernadero"],
"flows": [
{
"source": "Combustible",
"sink": "Electricidad",
"value": 50
},
{
"source": "Energía solar",
"sink": "Electricidad",
"value": 20
},
{
"source": "Energía eólica",
"sink": "Electricidad",
"value": 10
},
{
"source": "Combustible",
"sink": "Calor",
"value": 30
},
{
"source": "Combustible",
"sink": "Gases de efecto invernadero",
"value": 20
}
]
}

Generar diagramas estáticos con pySankey y Matplotlib:

Si estás buscando crear diagramas de Sankey estáticos, la biblioteca pySankey en Python, que se basa en matplotlib, es una excelente elección. Aquí tienes un ejemplo de cómo generar un diagrama de Sankey estático utilizando esta biblioteca:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.sankey import Sankey

# Definir los flujos entre nodos. Valores positivos son flujos hacia adelante,
# valores negativos son flujos hacia atrás (desde sumideros hacia fuentes).
flows = [0.4, 0.2, 0.3, -0.20, -0.15, -0.15, -0.25, -0.05] # Puedes modificar los valores de flujo

# Etiquetas para los nodos (fuentes y sumideros).
labels = ['', '', '', 'Primero', 'Segundo', 'Tercero', 'Cuarto', 'Quinto'] # Puedes modificar las etiquetas

# Orientaciones de los nodos. -1 es hacia arriba, 1 es hacia abajo, y 0 es horizontal.
orientations = [-1, 1, 0, 1, 1, -1, 0, -1] # Puedes modificar la dirección

# Genera el diagrama con los datos que hemos generado
sankey = Sankey(flows=flows, labels=labels, orientations=orientations).finish()
plt.title("Diagrama Sankey")
plt.show()

Personalización y optimización de diagramas de Sankey

Una de las ventajas de estos diagramas es su capacidad de personalización, lo que permite adaptarlos a las necesidades específicas de cada visualización. En esta sección, exploraremos cómo personalizar los colores de nodos y flujos, cómo utilizar grupos para colorear nodos relacionados y brindaremos consejos para evitar errores comunes y mejorar la legibilidad de los diagramas de Sankey.

Color personalizado de nodos individuales

El proceso inicial implica la creación de un objeto Javascript de enlaces de colores. Para cada nodo, se asigna un color específico. Luego, este objeto se utiliza en el argumento colourScale de la función networkD3.

# Bibliotecas
biblioteca(networkD3)
biblioteca(dplyr)

# Crear un marco de datos de conexiones
links <- data.frame(
source=c("group_A","group_A", "group_B", "group_C", "group_C", "group_E"),
target=c("group_C","group_D", "group_E", "group_F", "group_G", "group_H"),
value=c(2,3, 2, 3, 1, 3)
)

# A partir de estos flujos, necesitamos crear un marco de datos de nodos: lista todas las entidades involucradas en el flujo
nodes <- data.frame(
name=c(as.character(links$source), as.character(links$target)) %>%
unique()
)

# Con networkD3, la conexión debe proporcionarse usando ID, no el nombre real como en el marco de datos de enlaces... Así que necesitamos reformatearlo.
links$IDsource <- match(links$source, nodes$name)-1
links$IDtarget <- match(links$target, nodes$name)-1

# Preparar la escala de colores: asignar un color específico a cada nodo.
my_color <- 'd3.scaleOrdinal() .domain(["group_A", "group_B","group_C", "group_D", "group_E", "group_F", "group_G", "group_H"]) .range(["blue", "blue" , "blue", "red", "red", "yellow", "purple", "purple"])'

# Crear la Red. Llamo a mi escala de colores con el argumento colourScale
p <- sankeyNetwork(Links = links, Nodes = nodes, Source = "IDsource", Target = "IDtarget",
Value = "value", NodeID = "name", colourScale=my_color)
p

Asignar colores a grupos de nodos

Es posible asignar colores a los nodos en base a su pertenencia a un grupo específico. Usualmente, esta información se encuentra almacenada en una columna del marco de datos de nodos. Puedes utilizar esta información para crear un objeto de asignación de colores en JavaScript y luego emplearlo mediante el argumento NodeGroup.

# Agregar una columna 'group' al marco de datos de nodos:
nodes$group <- as.factor(c("a","a","a","a","a","b","b","b"))

# Asignar un color para cada grupo:
my_color <- 'd3.scaleOrdinal() .domain(["a", "b"]) .range(["#69b3a2", "steelblue"])'

# Crear el gráfico de red
p <- sankeyNetwork(Links = links, Nodes = nodes, Source = "IDsource", Target = "IDtarget",
Value = "value", NodeID = "name",
colourScale=my_color, NodeGroup="group")
p

Establecer color de las conexiones

Siguiendo el mismo principio, puedes controlar el color de cada flujo en tu diagrama:

# Agregar una columna 'grupo' a cada conexión:
links$group <- as.factor(c("tipo_a","tipo_a","tipo_a","tipo_b","tipo_b","tipo_b"))

# Agregar una columna 'grupo' a cada nodo. En este caso, decido ponerlos todos en el mismo grupo para que sean de color gris
nodes$group <- as.factor(c("mi_grupo_único"))

# Asignar un color para cada grupo:
my_color <- 'd3.scaleOrdinal() .domain(["tipo_a", "tipo_b", "mi_grupo_único"]) .range(["#69b3a2", "steelblue", "grey"])'

# Crear la Red
p <- sankeyNetwork(Links = links, Nodes = nodes, Source = "IDsource", Target = "IDtarget",
Value = "value", NodeID = "name",
colourScale=my_color, LinkGroup="group", NodeGroup="group")

p

Exportación e Interactividad

Los diagramas de Sankey no solo son una poderosa herramienta para visualizar flujos y relaciones, sino que también ofrecen la flexibilidad de ser compartidos y explorados en diferentes formatos y niveles de interacción. En esta sección, exploraremos cómo exportar los diagramas a formatos estáticos y cómo aprovechar la interactividad inherente a ciertas bibliotecas de creación de diagramas.

Exportación a Formatos Estáticos

Aunque los diagramas de Sankey son inherentemente dinámicos y pueden interactuarse en tiempo real, a veces es necesario exportarlos en formatos estáticos para su inclusión en informes, presentaciones u otras plataformas. Veamos cómo hacerlo utilizando diferentes bibliotecas.

  • Exportación en R con networkD3 y htmlwidgets

La biblioteca networkD3 en R permite exportar el diagrama de Sankey en formato HTML, el cual puede integrarse en documentos o páginas web. Sin embargo, si necesitas un formato de imagen estática, puedes utilizar la biblioteca webshot para capturar una imagen de la versión renderizada del diagrama.

# Crear un archivo HTML con el grafico
library(htmlwidgets)
saveWidget(p, file=paste0( getwd(), "/sankeyBasic1.html"))

# Capturar el HTML en un archivo PNG
install.packages("webshot")
library(webshot)

webshot::webshot("ruta_al_archivo.html", "diagrama_sankey.png")

Exportación en Python con Plotly y webshot

De manera similar, en Python, puedes exportar un diagrama de Sankey en formato HTML utilizando Plotly. Luego, puedes utilizar la biblioteca webshot para capturar una imagen estática del diagrama.

import plotly.graph_objects as go
import webshot

# Crear el diagrama de Sankey con Plotly
fig = go.Figure(go.Sankey(...))

# Guardar el diagrama en formato HTML
fig.write_html("diagrama_sankey.html")

# Capturar una captura de pantalla del diagrama HTML
webshot.capturedir()
webshot.url('file:///ruta_al_archivo.html', "diagrama_sankey.png")

Interactividad

Una de las ventajas clave de las bibliotecas de creación de diagramas es la interactividad que ofrecen. A continuación, te mostramos cómo aprovechar esta interactividad en los diagramas de Sankey.

La biblioteca networkD3 en R genera diagramas de Sankey interactivos por defecto. Puedes hacer clic en los nodos y enlaces para resaltar los flujos y explorar la estructura del diagrama.

Por otra parte Plotly genera diagramas de Sankey interactivos en Python. Puedes mover el cursor sobre los nodos y enlaces para obtener información detallada sobre los flujos y los valores.

La única librería que no ofrece diagramas interactivos son aquellos que hemos creado previamente con matplotlib.

A medida que las herramientas y bibliotecas de creación de diagramas se vuelven más accesibles y poderosas, es el momento perfecto para integrar el diagrama de Sankey en tu caja de herramientas de visualización. Ya sea que busques optimizar flujos en tu cadena de suministro, comprender el consumo de energía en un sistema industrial o identificar patrones en datos complejos, el diagrama de Sankey se alza como un recurso confiable.

La capacidad de personalizar colores, agrupar nodos y aprovechar la interactividad proporcionada por bibliotecas como networkD3 y Plotly abre un mundo de posibilidades para dar vida a tus diagramas y contar historias aún más convincentes. Invitamos a los lectores a explorar estas herramientas, experimentar con datos y sumergirse en la fascinante red de flujos y conexiones que los diagramas de Sankey pueden revelar.

En última instancia, el diagrama de Sankey trasciende las barreras del lenguaje y la complejidad, permitiéndonos comunicar conceptos abstractos y procesos detallados de manera clara y efectiva. Su impacto en la visualización de datos es innegable, y su capacidad para arrojar luz sobre lo que estaba oculto en los números es un recordatorio constante del poder de la representación visual en el análisis y la comunicación de información.

--

--

Nicolás Urrego

Data Scientis | Data Analyst | Data Base | Machine Learning | Communicator | El mundo de datos en español para descubrir, aprender y compartir. 💡👨‍💻📈