tutoriales.com

Unveiling Historias Visuales: Creando Narrativas con Gráficos de Área Apilados en Python

Descubre el poder de los gráficos de área apilados para visualizar cómo las partes contribuyen a un todo a lo largo del tiempo o de una categoría. Este tutorial te guiará paso a paso para crear narrativas de datos convincentes usando Python.

Principiante15 min de lectura30 views
Reportar error

Los gráficos de área apilados son herramientas poderosas en la visualización de datos, especialmente cuando queremos mostrar la evolución de varias categorías que contribuyen a un total. Son excelentes para ilustrar cómo la composición de un todo cambia con el tiempo o a través de diferentes segmentos.

En este tutorial, exploraremos cómo crear y personalizar gráficos de área apilados en Python utilizando las librerías Matplotlib y Seaborn. Abordaremos desde la preparación de datos hasta la interpretación de los resultados, asegurándonos de que puedas contar historias claras y persuasivas con tus visualizaciones.

🎯 ¿Por Qué Gráficos de Área Apilados?

Imagina que quieres visualizar la evolución de las ventas por departamento en una empresa a lo largo de los años. Un gráfico de área apilado te permitiría ver no solo el total de ventas anuales, sino también la contribución de cada departamento a ese total, y cómo esa contribución ha variado con el tiempo.

💡 Consejo: Los gráficos de área apilados son ideales para mostrar **cambios en la composición** y **tendencias agregadas** simultáneamente.

Casos de Uso Comunes:

  • Demografía: Evolución de la población por grupos de edad.
  • Finanzas: Desglose de ingresos o gastos por categoría a lo largo del tiempo.
  • Mercado: Cuota de mercado de diferentes productos en un sector.
  • Recursos: Consumo de energía por fuente (solar, eólica, fósil) a lo largo de los meses.

🛠️ Herramientas Necesarias

Para este tutorial, solo necesitarás Python y algunas de sus librerías más populares para la ciencia de datos y la visualización:

  • Python: La base de nuestro trabajo.
  • Pandas: Para la manipulación y preparación de datos.
  • Matplotlib: La librería fundamental para crear gráficos en Python.
  • Seaborn: Construida sobre Matplotlib, ofrece interfaces de alto nivel para gráficos atractivos.
100% Cubierto

Instalación de Librerías

Si aún no las tienes instaladas, puedes hacerlo fácilmente usando pip:

pip install pandas matplotlib seaborn

📊 Preparación de Datos: El Primer Paso

Antes de visualizar, necesitamos datos. Para nuestro ejemplo, simularemos datos de ventas mensuales por diferentes categorías de productos durante un año.

Creando un DataFrame de Ejemplo

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

# Establecer una semilla para reproducibilidad
np.random.seed(42)

# Crear fechas para un año
dates = pd.date_range(start='2023-01-01', periods=12, freq='M')

# Categorías de productos
products = ['Electrónica', 'Hogar', 'Ropa', 'Alimentos']

# Generar datos de ventas aleatorias con cierta tendencia
data = {
    'Fecha': np.repeat(dates, len(products)),
    'Producto': np.tile(products, len(dates)),
    'Ventas': np.random.randint(100, 500, size=len(dates) * len(products)) * np.tile(np.linspace(1, 1.5, len(products)), len(dates)) # Añadir una ligera tendencia a los productos
}

df = pd.DataFrame(data)

# Ajustar un poco más las ventas para que sean más interesantes y no completamente planas
for i, product in enumerate(products):
    df.loc[df['Producto'] == product, 'Ventas'] = df.loc[df['Producto'] == product, 'Ventas'] * (1 + 0.1 * i + np.random.randn(12) * 0.05)

df['Ventas'] = df['Ventas'].round(0).astype(int)

print(df.head())

El resultado debería ser similar a esto:

        Fecha     Producto  Ventas
0  2023-01-31  Electrónica     123
1  2023-01-31        Hogar     245
2  2023-01-31         Ropa     350
3  2023-01-31    Alimentos     601
4  2023-02-28  Electrónica     150

Para un gráfico de área apilado, es común tener los datos en un formato ancho, donde cada columna representa una categoría y las filas representan el tiempo o la variable categórica principal. Podemos pivotar nuestro DataFrame.

df_pivot = df.pivot_table(index='Fecha', columns='Producto', values='Ventas')
print(df_pivot.head())
Producto    Alimentos  Electrónica  Hogar  Ropa
Fecha                                          
2023-01-31        601          123    245   350
2023-02-28        587          150    223   367
2023-03-31        654          128    256   378
2023-04-30        605          147    210   375
2023-05-31        612          135    252   390

📈 Creando Gráficos de Área Apilados con Matplotlib

Matplotlib nos ofrece la función stackplot para crear gráficos de área apilados directamente.

Gráfico Básico

plt.figure(figsize=(12, 6))
plt.stackplot(df_pivot.index, df_pivot['Alimentos'], df_pivot['Electrónica'], df_pivot['Hogar'], df_pivot['Ropa'], labels=df_pivot.columns)

plt.xlabel('Fecha')
plt.ylabel('Ventas Totales')
plt.title('Ventas Mensuales por Categoría de Producto (Matplotlib)')
plt.legend(loc='upper left')
plt.grid(True, linestyle='--', alpha=0.6)
plt.tight_layout()
plt.show()
Ventas Mensuales por Categoría (2023) Ropa Hogar Electrónica Alimentos 0 50 100 150 200 250 Ventas Totales Ene Feb Mar Abr May Jun Jul Ago Sep Oct Nov Dic Fecha (2023)

Este código genera un gráfico de área apilado básico. Puedes ver cómo las ventas totales cambian con el tiempo y cómo la contribución de cada producto varía.

Personalizando el Gráfico con Matplotlib

Podemos mejorar la estética y la legibilidad de nuestro gráfico.

Paso 1: Ajustar los colores para mayor contraste y atractivo visual.
Paso 2: Mejorar las etiquetas y el título para mayor claridad.
Paso 3: Añadir marcadores o anotaciones si es necesario.
Paso 4: Formatear el eje X para mostrar los meses de manera más legible.
colors = ['#FF9999', '#66B2FF', '#99FF99', '#FFCC99'] # Colores pastel

plt.figure(figsize=(14, 7))

plt.stackplot(df_pivot.index, 
              df_pivot['Alimentos'], 
              df_pivot['Electrónica'], 
              df_pivot['Hogar'], 
              df_pivot['Ropa'], 
              labels=df_pivot.columns, 
              colors=colors, 
              edgecolor='black', 
              linewidth=0.5)

# Formatear el eje X para mostrar solo el mes
plt.gca().xaxis.set_major_formatter(plt.matplotlib.dates.DateFormatter('%b'))
plt.gca().xaxis.set_major_locator(plt.matplotlib.dates.MonthLocator())

plt.xlabel('Mes', fontsize=12)
plt.ylabel('Ventas Totales ($)', fontsize=12)
plt.title('Tendencia de Ventas Mensuales por Categoría de Producto', fontsize=16, pad=20)
plt.legend(title='Categoría de Producto', loc='upper left', bbox_to_anchor=(1, 1))
plt.grid(True, linestyle=':', alpha=0.7)
plt.xticks(rotation=45)
plt.tight_layout(rect=[0, 0, 0.88, 1]) # Ajustar para la leyenda fuera del gráfico
plt.show()
Evolución Trimestral de Ventas por Categoría Enero Febrero Marzo Abril Mayo Junio 0 50 100 150 200 Categorías Hogar Ropa Electrónica
📌 Nota: Usar `tight_layout` con `rect` es útil cuando la leyenda se coloca fuera del área principal del gráfico para evitar que se superponga.

🌈 Gráficos de Área Apilados con Seaborn

Seaborn, al estar construido sobre Matplotlib, puede generar gráficos de área apilados de forma elegante, aunque su función principal para esto es a menudo a través de histplot o kdeplot con el parámetro stack=True para distribuciones, o usando FacetGrid para más flexibilidad con datos de series temporales. Sin embargo, para un enfoque directo de series temporales, a menudo volvemos a Matplotlib después de una buena preparación con Pandas.

Una forma común de usar Seaborn con gráficos de área es preprocesar los datos y luego usar plt.stackplot con los datos ya ordenados por Seaborn si fuera necesario para otras visualizaciones, o usando relplot con kind='line' y luego rellenando.

Para un gráfico de área apilado puro, Seaborn no tiene una función stackplot directa como Matplotlib. Sin embargo, podemos usar sus paletas de colores y estilos para mejorar un gráfico de Matplotlib.

Mejorando la Estética con Seaborn Styles

sns.set_style('whitegrid') # Establecer un estilo de Seaborn
sns.set_palette('pastel') # Usar una paleta de colores de Seaborn

plt.figure(figsize=(14, 7))

plt.stackplot(df_pivot.index, 
              df_pivot['Alimentos'], 
              df_pivot['Electrónica'], 
              df_pivot['Hogar'], 
              df_pivot['Ropa'], 
              labels=df_pivot.columns,
              edgecolor='black', 
              linewidth=0.5)

plt.gca().xaxis.set_major_formatter(plt.matplotlib.dates.DateFormatter('%b'))
plt.gca().xaxis.set_major_locator(plt.matplotlib.dates.MonthLocator())

plt.xlabel('Mes', fontsize=12)
plt.ylabel('Ventas Totales ($)', fontsize=12)
plt.title('Tendencia de Ventas Mensuales por Categoría de Producto (Estilo Seaborn)', fontsize=16, pad=20)
plt.legend(title='Categoría de Producto', loc='upper left', bbox_to_anchor=(1, 1))
plt.xticks(rotation=45)
plt.tight_layout(rect=[0, 0, 0.88, 1])
plt.show()

sns.reset_orig() # Volver al estilo original de Matplotlib para no afectar otros gráficos
Análisis de Rendimiento Trimestral Ene Feb Mar Abr May Jun 0 100 200 300 Producto C Producto B Producto A

Aquí, Seaborn se utiliza para aplicar un estilo general y una paleta de colores, haciendo que el gráfico de stackplot de Matplotlib se vea más profesional con menos esfuerzo.


💡 Interpretando Gráficos de Área Apilados

La clave para interpretar estos gráficos es observar tanto la altura total de la pila como la anchura de cada una de sus capas.

  • Altura Total: Representa el valor agregado (por ejemplo, ventas totales) en cada punto del eje X.
  • Anchura de las Capas: Indica la contribución relativa de cada categoría al total en un momento dado. Una capa más ancha significa una mayor proporción.

Ejemplo de Interpretación

Si la capa de 'Alimentos' ocupa una gran parte del área total consistentemente, indica que 'Alimentos' es el principal motor de ventas. Si la capa de 'Electrónica' crece significativamente en los últimos meses mientras otras disminuyen, sugiere un cambio en las preferencias del mercado o una estrategia de marketing exitosa para esa categoría.

⚠️ Advertencia: Ten cuidado al comparar el crecimiento de categorías individuales mirando solo la *altura absoluta* de su capa, ya que el punto de partida de cada capa es variable. Es mejor enfocarse en la **anchura relativa** y la **tendencia general** de cada capa. Para comparaciones directas de crecimiento individual, un gráfico de líneas superpuestas podría ser más adecuado.

🧩 Variaciones y Mejoras Avanzadas

Gráficos de Área Apilados Normalizados (Porcentuales)

En ocasiones, puede ser más interesante ver la proporción de cada categoría en relación con el total, en lugar de los valores absolutos. Esto se logra normalizando los datos para que el total de cada punto en el eje X sume 100%.

df_pivot_percent = df_pivot.div(df_pivot.sum(axis=1), axis=0) * 100

plt.figure(figsize=(14, 7))

plt.stackplot(df_pivot_percent.index, 
              df_pivot_percent['Alimentos'], 
              df_pivot_percent['Electrónica'], 
              df_pivot_percent['Hogar'], 
              df_pivot_percent['Ropa'], 
              labels=df_pivot_percent.columns, 
              colors=sns.color_palette('viridis', n_colors=len(products)), # Otra paleta de Seaborn
              edgecolor='black', 
              linewidth=0.5)

plt.gca().xaxis.set_major_formatter(plt.matplotlib.dates.DateFormatter('%b'))
plt.gca().xaxis.set_major_locator(plt.matplotlib.dates.MonthLocator())

plt.xlabel('Mes', fontsize=12)
plt.ylabel('Porcentaje de Ventas (%)', fontsize=12)
plt.title('Ventas Mensuales por Categoría de Producto (Normalizado al 100%)', fontsize=16, pad=20)
plt.legend(title='Categoría de Producto', loc='upper left', bbox_to_anchor=(1, 1))
plt.grid(True, linestyle=':', alpha=0.7)
plt.xticks(rotation=45)
plt.tight_layout(rect=[0, 0, 0.88, 1])
plt.show()
Distribución de Ventas Mensuales (100%) Alimentos Electrónica Hogar Ropa 0% 25% 50% 75% 100% Ene Feb Mar Abr May Jun Jul Ago Sep Oct Nov Dic

Este tipo de gráfico es excelente para ver cómo la composición cambia, incluso si el total general de ventas no varía mucho.

Añadiendo Anotaciones y Énfasis

Para resaltar eventos específicos o cambios importantes, puedes añadir anotaciones.

Ejemplo de anotación
# ... (código del stackplot anterior)

# Añadir una anotación para un evento específico (ej. lanzamiento de un producto en Mayo)
plt.annotate('Lanzamiento Nuevo Producto', 
             xy=(pd.Timestamp('2023-05-31'), 75), # Coordenadas X, Y
             xytext=(pd.Timestamp('2023-07-31'), 90), # Coordenadas de la etiqueta
             arrowprops=dict(facecolor='black', shrink=0.05), 
             fontsize=10,
             color='red')

plt.show()

Esto es muy útil para contar la historia detrás de los datos, vinculando los cambios visuales con eventos del mundo real.


✅ Buenas Prácticas y Consideraciones

  • Número de Categorías: Evita apilar demasiadas categorías. Si tienes muchas, las capas inferiores pueden volverse demasiado delgadas y difíciles de distinguir. Considera agrupar las categorías pequeñas en 'Otros'.
  • Orden de las Capas: El orden importa. Generalmente, coloca las categorías más estables o fundamentales en la base y las más volátiles o de interés secundario en la parte superior. A veces, ordenar por tamaño promedio también es una buena estrategia.
  • Colores: Usa una paleta de colores que sea fácilmente distinguible y que no distraiga. Seaborn tiene excelentes paletas (pastel, viridis, plasma, etc.).
  • Interactividad: Para conjuntos de datos más complejos o para permitir una exploración más profunda, considera librerías interactivas como Plotly o Bokeh, que permiten a los usuarios hacer zoom, seleccionar capas y ver tooltips con información detallada.
  • Transparencia: Si las capas se superponen o tienes valores cero que podrían ocultar otras capas, el uso de transparencia (alpha en stackplot) puede ayudar.
| Característica | Bueno para Gráficos de Área Apilados | Malo para Gráficos de Área Apilados | | :--------------------- | :----------------------------------- | :---------------------------------- | | --- | --- | --- | | **Cambio de Composición** | ✅ Excelente | ❌ Difícil con muchos cambios de orden | | **Total Agregado** | ✅ Muy bueno | ❌ No es su función principal | | --- | --- | --- | | **Comparación de Partes** | ✅ Bueno (relativa) | ❌ Difícil (absoluta) | | **Tendencias Temporales** | ✅ Excelente | ❌ No apto para valores negativos | | --- | --- | --- | | **Número de Series** | 3-7 series | >10 series |

🚀 Conclusión

Los gráficos de área apilados son una herramienta valiosa en tu arsenal de visualización de datos, permitiéndote contar historias convincentes sobre cómo las partes contribuyen a un todo y cómo estas contribuciones evolucionan. Con Matplotlib y Seaborn en Python, tienes todo lo necesario para crear visualizaciones informativas y estéticamente agradables.

Recuerda siempre elegir el tipo de gráfico adecuado para tu mensaje y tus datos, y personalizarlo para maximizar su claridad e impacto. ¡Ahora estás listo para desvelar esas historias visuales con confianza!

Tutoriales relacionados

Comentarios (0)

Aún no hay comentarios. ¡Sé el primero!