tutoriales.com

Cuentacuentos con Datos: Visualizando Distribuciones con Histogramas y KDE en Python

Este tutorial te guiará paso a paso en la creación de histogramas y gráficos de Estimación de Densidad de Kernel (KDE) en Python. Descubre cómo estas herramientas de visualización son esenciales para entender la distribución de tus datos, identificar patrones, detectar valores atípicos y comunicar insights de manera efectiva.

Principiante15 min de lectura3 views
Reportar error

📊 Introducción al Cuentacuentos con Datos

En el fascinante mundo de la Ciencia de Datos, comprender la distribución de una variable es fundamental para extraer información valiosa. No basta con conocer la media o la mediana; necesitamos visualizar cómo se extienden los datos, dónde se concentran, si hay picos múltiples o si la distribución es simétrica. Aquí es donde los histogramas y las estimaciones de densidad de kernel (KDE) entran en juego, actuando como nuestros ojos para "ver" la forma de nuestros datos.

Este tutorial te equipará con las herramientas y el conocimiento necesarios para utilizar Matplotlib y Seaborn en Python, transformando tus datos crudos en visualizaciones significativas que cuenten una historia clara y concisa.

¿Por qué son importantes la distribución de datos?

La distribución de datos nos revela la frecuencia de los valores dentro de un conjunto. Imagina que tienes datos sobre el salario de los empleados de una empresa. ¿La mayoría gana cerca del promedio, o hay muchos salarios bajos y pocos muy altos? La forma de la distribución responde a estas preguntas, lo que es crucial para la toma de decisiones.

💡 Consejo: Una buena comprensión de la distribución de tus datos es el primer paso para realizar análisis estadísticos más complejos y para identificar posibles problemas o anomalías.

🛠️ Herramientas Necesarias

Para seguir este tutorial, necesitarás una instalación de Python y las siguientes bibliotecas:

  • pandas: Para la manipulación y carga de datos.
  • matplotlib: La biblioteca base para la creación de gráficos en Python.
  • seaborn: Construida sobre matplotlib, ofrece una interfaz de alto nivel para crear gráficos estadísticos atractivos.

Instalación de las Bibliotecas

Si aún no tienes estas bibliotecas, puedes instalarlas fácilmente usando pip:

pip install pandas matplotlib seaborn
📌 Nota: Es recomendable trabajar en un entorno virtual para mantener las dependencias de tus proyectos organizadas.

📈 Entendiendo los Histogramas

Un histograma es una representación gráfica de la distribución de un conjunto de datos numéricos. Divide el rango de valores de una variable en una serie de intervalos (llamados bins o clases) y luego cuenta cuántos puntos de datos caen en cada intervalo. La altura de cada barra en el histograma representa la frecuencia de los datos dentro de ese intervalo.

Anatomía de un Histograma

  • Eje X: Representa los rangos de valores de la variable (los bins).
  • Eje Y: Representa la frecuencia o el recuento de observaciones en cada bin.
  • Barras: Cada barra corresponde a un bin y su altura indica la frecuencia.
Anatomía de un Histograma Rangos de Valores (Bins) Frecuencia Bin 1 Bin 2 Bin 3 Bin 4 Bin 5 0 10 20 30 40

Cuándo usar Histogramas

Los histogramas son ideales para:

  • Visualizar la forma general de la distribución de una variable.
  • Identificar la tendencia central, la dispersión y la asimetría de los datos.
  • Detectar posibles valores atípicos (outliers).
  • Comprender si una distribución es unimodal (un pico), bimodal (dos picos) o multimodal.

Creando un Histograma Básico con Matplotlib

Vamos a empezar cargando algunos datos de ejemplo y creando nuestro primer histograma.

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

# Generar datos de ejemplo: una distribución normal
np.random.seed(42)
data = np.random.normal(loc=50, scale=10, size=1000) # Media 50, Desviación estándar 10

plt.figure(figsize=(10, 6))
plt.hist(data, bins=30, edgecolor='black', alpha=0.7)
plt.title('Histograma Básico de Datos Normales')
plt.xlabel('Valor')
plt.ylabel('Frecuencia')
plt.grid(axis='y', alpha=0.75)
plt.show()

En este código:

  • plt.hist(): Es la función principal para crear histogramas.
    • data: Los datos que queremos visualizar.
    • bins: El número de intervalos (barras) en el histograma. Elegir un número adecuado de bins es crucial; muy pocos ocultarán detalles, y demasiados harán que el gráfico parezca ruidoso.
    • edgecolor: Define el color del borde de las barras.
    • alpha: Ajusta la transparencia de las barras.

Ajustando los Bins

La elección del número de bins puede afectar drásticamente la apariencia y la interpretación de un histograma. Experimentar con diferentes valores es una buena práctica.

Número de BinsDescripciónImpacto en la Visualización
---------
Pocos (ej. 5)Agrupación excesiva de datos.Oculta detalles, puede dar una imagen engañosa de la distribución.
Moderados (ej. 10-30)Buen equilibrio, muestra la forma general.Generalmente el más útil para comprender la distribución subyacente.
---------
Muchos (ej. 100+)Demasiado detalle, puede parecer ruidoso.Cada barra podría contener muy pocos puntos, dificultando la identificación de patrones.
plt.figure(figsize=(12, 5))

plt.subplot(1, 2, 1) # 1 fila, 2 columnas, primer gráfico
plt.hist(data, bins=5, edgecolor='black', alpha=0.7)
plt.title('Histograma con 5 Bins')
plt.xlabel('Valor')
plt.ylabel('Frecuencia')

plt.subplot(1, 2, 2) # 1 fila, 2 columnas, segundo gráfico
plt.hist(data, bins=50, edgecolor='black', alpha=0.7)
plt.title('Histograma con 50 Bins')
plt.xlabel('Valor')
plt.ylabel('Frecuencia')

plt.tight_layout() # Ajusta automáticamente los parámetros de la subtrama para que encajen en el área de la figura.
plt.show()

🌊 Estimación de Densidad de Kernel (KDE)

Mientras que un histograma nos da un recuento discreto de frecuencias por bin, la Estimación de Densidad de Kernel (KDE) proporciona una curva suave que representa la distribución de probabilidad de la variable. Es como una versión suavizada del histograma, lo que nos ayuda a inferir la función de densidad de probabilidad (PDF) subyacente de la población de la que provienen los datos.

¿Cómo funciona KDE?

KDE funciona colocando una "función kernel" (generalmente una función de campana gaussiana) en cada punto de datos. Luego, suma todas estas funciones kernel para crear una estimación suave de la densidad de probabilidad. El ancho de banda (bandwidth) del kernel es un parámetro clave que controla la suavidad de la curva.

Estimación de Densidad de Núcleo (KDE) 1. Núcleos Individuales (Gaussianos) Σ 2. Densidad Agregada (Suma) Kernels locales Función KDE final Valores de la Variable (Eje X)

Cuándo usar KDE

KDE es excelente para:

  • Visualizar la forma subyacente de la distribución sin la dependencia de los bins.
  • Comparar las distribuciones de diferentes grupos en el mismo gráfico.
  • Identificar la multimodalidad o asimetría de forma más clara que un histograma.
  • Presentar una estimación más continua y elegante de la distribución.

Creando un Gráfico KDE Básico con Seaborn

Seaborn facilita enormemente la creación de gráficos KDE, a menudo combinándolos con histogramas para una visualización más completa.

import seaborn as sns

plt.figure(figsize=(10, 6))
sns.histplot(data, kde=True, bins=30, color='skyblue', edgecolor='black')
plt.title('Histograma y KDE de Datos Normales con Seaborn')
plt.xlabel('Valor')
plt.ylabel('Frecuencia / Densidad')
plt.grid(axis='y', alpha=0.75)
plt.show()

En este ejemplo, sns.histplot(kde=True) no solo dibuja el histograma, sino que también superpone la curva KDE, lo que nos permite ver la relación entre la frecuencia de los bins y la densidad estimada.

Controlando el Ancho de Banda (Bandwidth) del KDE

El parámetro bw_adjust (o bw_method en versiones anteriores) en Seaborn controla la suavidad de la curva KDE. Un valor más pequeño produce una curva más "picada" (menos suavizada), mientras que un valor más grande produce una curva más suave (más suavizada).

plt.figure(figsize=(12, 5))

plt.subplot(1, 2, 1)
sns.histplot(data, kde=True, bins=30, color='lightcoral', edgecolor='black', kde_kws={'bw_adjust': 0.2})
plt.title('KDE con ancho de banda pequeño (0.2)')
plt.xlabel('Valor')
plt.ylabel('Frecuencia / Densidad')

plt.subplot(1, 2, 2)
sns.histplot(data, kde=True, bins=30, color='lightgreen', edgecolor='black', kde_kws={'bw_adjust': 2})
plt.title('KDE con ancho de banda grande (2)')
plt.xlabel('Valor')
plt.ylabel('Frecuencia / Densidad')

plt.tight_layout()
plt.show()
⚠️ Advertencia: Elegir un ancho de banda incorrecto puede llevar a interpretaciones erróneas. Un ancho de banda muy pequeño puede mostrar ruido, y uno muy grande puede ocultar características importantes de la distribución.

🎯 Combinando Histogramas y KDE: Un Enfoque Completo

La combinación de histogramas y KDE en un solo gráfico ofrece lo mejor de ambos mundos: la robustez del recuento de bins y la elegancia de la curva de densidad suave. Seaborn facilita esto enormemente.

Caso Práctico: Datos de Salarios

Imaginemos que tenemos un conjunto de datos ficticio de salarios en una empresa y queremos entender su distribución.

# Generar datos de salarios con una ligera asimetría
salarios = np.concatenate([
    np.random.normal(loc=35000, scale=5000, size=700),
    np.random.normal(loc=60000, scale=10000, size=300) # Algunos salarios más altos
])
salarios = np.maximum(15000, salarios) # Asegurarse de que no haya salarios negativos o muy bajos

plt.figure(figsize=(12, 7))
sns.histplot(salarios, kde=True, bins=50, color='purple', edgecolor='black', stat='density', alpha=0.6)
plt.title('Distribución de Salarios en la Empresa', fontsize=16)
plt.xlabel('Salario (€)', fontsize=12)
plt.ylabel('Densidad de Probabilidad', fontsize=12)
plt.axvline(np.mean(salarios), color='red', linestyle='dashed', linewidth=1.5, label=f'Media: {np.mean(salarios):.2f}')
plt.axvline(np.median(salarios), color='green', linestyle='dashed', linewidth=1.5, label=f'Mediana: {np.median(salarios):.2f}')
plt.legend()
plt.grid(axis='y', alpha=0.75)
plt.show()

En este gráfico:

  • stat='density': Hace que el eje Y muestre la densidad de probabilidad en lugar de la frecuencia bruta, lo que es útil cuando se superpone con un KDE.
  • Hemos añadido líneas verticales para la media y la mediana, que son medidas clave de tendencia central. Su posición relativa nos da pistas sobre la asimetría de la distribución.

🔥 Interpretación Clave:

Si la media es mayor que la mediana, la distribución probablemente esté sesgada a la derecha (tiene una cola más larga hacia valores más altos). Si la mediana es mayor que la media, está sesgada a la izquierda. En nuestro ejemplo de salarios, la media es probablemente más alta que la mediana debido a los salarios más altos, lo que indica un sesgo a la derecha.


👥 Comparando Distribuciones

Una de las aplicaciones más poderosas de KDE es la comparación de distribuciones entre diferentes grupos o categorías. Seaborn lo hace muy intuitivo.

Ejemplo: Distribución de Edad por Género

Crearemos un conjunto de datos ficticio de edades y géneros para ilustrar esto.

# Generar datos de ejemplo
df = pd.DataFrame({
    'Edad': np.concatenate([
        np.random.normal(loc=30, scale=5, size=500),
        np.random.normal(loc=35, scale=7, size=500)
    ]),
    'Género': ['Masculino']*500 + ['Femenino']*500
})
df['Edad'] = df['Edad'].apply(lambda x: max(18, min(70, x))) # Limitar edades a un rango razonable

plt.figure(figsize=(10, 6))
sns.histplot(data=df, x='Edad', hue='Género', kde=True, palette='viridis', stat='density', common_norm=False)
plt.title('Distribución de Edad por Género', fontsize=16)
plt.xlabel('Edad', fontsize=12)
plt.ylabel('Densidad de Probabilidad', fontsize=12)
plt.grid(axis='y', alpha=0.75)
plt.show()

Aquí, el parámetro hue='Género' le dice a Seaborn que cree diferentes histogramas y curvas KDE para cada categoría en la columna 'Género'. common_norm=False es importante para que cada distribución se normalice de forma independiente, permitiendo una mejor comparación de sus formas relativas, incluso si los tamaños de los grupos son diferentes.

💡 Consejo: Utiliza `common_norm=True` si quieres que el área total bajo todas las curvas sume 1, útil para comparar proporciones relativas entre grupos. Para comparar la FORMA de las distribuciones, `common_norm=False` es generalmente mejor.

Parámetros clave de sns.histplot

  • x, y: La(s) variable(s) para el histograma.
  • hue: Variable categórica para agrupar los datos y mostrar diferentes distribuciones.
  • weights: Ponderaciones para cada observación.
  • stat: La estadística a calcular para el eje Y ('count', 'frequency', 'density', 'probability').
  • bins: Número de intervalos o la definición de los bordes de los intervalos.
  • kde: Si se debe superponer una estimación de densidad de kernel (True/False).
  • element: Cómo dibujar el histograma ('bars', 'step', 'poly').
  • fill: Si se deben rellenar las barras del histograma (True/False).
  • palette: Conjunto de colores para las diferentes categorías del hue.

✨ Estilización Avanzada y Personalización

Una buena visualización no solo es precisa, sino también atractiva y fácil de entender. Matplotlib y Seaborn ofrecen una amplia gama de opciones de personalización.

Añadiendo Títulos, Etiquetas y Leyendas

Siempre asegúrate de que tus gráficos tengan títulos claros, etiquetas de ejes descriptivas y leyendas cuando sea necesario.

plt.figure(figsize=(10, 6))
sns.histplot(data, kde=True, bins=25, color='#1f77b4', edgecolor='darkblue', alpha=0.8, stat='density', label='Densidad de Datos')

# Personalización de títulos y etiquetas
plt.title('Distribución de Datos con Colores Personalizados', fontsize=18, fontweight='bold', color='darkslategray')
plt.xlabel('Valor de la Variable', fontsize=14, color='darkgray')
plt.ylabel('Densidad', fontsize=14, color='darkgray')

# Añadir leyenda y ajustar su posición
plt.legend(loc='upper left', frameon=True, shadow=True, fancybox=True, fontsize=10)

# Personalizar ticks de los ejes
plt.xticks(fontsize=10)
plt.yticks(fontsize=10)

# Eliminar el borde superior y derecho del gráfico para una apariencia más limpia
sns.despine(left=False, bottom=False)

plt.show()

Gráficos Solo KDE

Si solo necesitas la curva de densidad sin el histograma, puedes usar sns.kdeplot directamente.

plt.figure(figsize=(10, 6))
sns.kdeplot(data=df, x='Edad', hue='Género', fill=True, palette='coolwarm', alpha=0.7, linewidth=2)
plt.title('Curvas KDE de Edad por Género', fontsize=16)
plt.xlabel('Edad', fontsize=12)
plt.ylabel('Densidad', fontsize=12)
plt.grid(axis='y', alpha=0.75, linestyle='--', linewidth=0.5)
plt.show()

Aquí, fill=True rellena el área bajo cada curva, lo que puede ser visualmente atractivo para comparar la magnitud de las densidades.

90% Completado

✅ Buenas Prácticas y Consejos

Para crear visualizaciones efectivas, considera las siguientes pautas:

  • Claridad: Asegúrate de que tu gráfico sea fácil de entender a primera vista.
  • Precisión: Representa los datos de forma fiel. Evita distorsiones.
  • Contexto: Proporciona suficiente información (títulos, etiquetas, unidades) para que el lector pueda interpretar el gráfico correctamente.
  • Coherencia: Usa un estilo consistente en todos tus gráficos (colores, fuentes, etc.).
  • Iteración: Experimenta con diferentes números de bins y anchos de banda para encontrar la mejor representación para tus datos.
Paso 1: Entender el Objetivo - ¿Qué historia quieres que cuenten tus datos?
Paso 2: Elegir la Herramienta Correcta - Histograma para recuentos discretos, KDE para densidad suave.
Paso 3: Explorar Parámetros - Ajusta bins, ancho de banda, etc.
Paso 4: Estilizar para Claridad - Títulos, etiquetas, leyendas, colores.
Paso 5: Interpretar y Comunicar - Extrae insights y explícalos claramente.

🚀 Conclusión

Los histogramas y los gráficos de Estimación de Densidad de Kernel (KDE) son herramientas indispensables en tu arsenal de visualización de datos. Te permiten ir más allá de los resúmenes estadísticos básicos y realmente "ver" la forma, la dispersión y los patrones ocultos dentro de tus conjuntos de datos.

Al dominar estas técnicas con Matplotlib y Seaborn, estarás mejor equipado para explorar tus datos, validar suposiciones, detectar anomalías y, en última instancia, contar historias de datos más convincentes y precisas.

¡Ahora es tu turno de aplicar estos conocimientos y transformar tus datos en visualizaciones impactantes!

Tutoriales relacionados

Comentarios (0)

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