Imagen destacada del tutorial: Gráficos Avanzados con Matplotlib: Visualizaciones Estadísticas y Complejas
Matplotlib

Gráficos Avanzados con Matplotlib: Visualizaciones Estadísticas y Complejas

José Elías Romero Guanipa
01 Sep 2025

Aprende a crear gráficos avanzados con Matplotlib: histogramas, mapas de calor, diagramas de caja, gráficos polares y visualizaciones estadísticas complejas.

matplotlib python visualizacion estadistica histogramas +3 más

¡Lleva tus visualizaciones al siguiente nivel! En este tutorial aprenderás a crear gráficos avanzados y visualizaciones estadísticas complejas con Matplotlib, incluyendo histogramas, mapas de calor, diagramas de caja, gráficos polares y mucho más.

Objetivo: Dominar las técnicas avanzadas de visualización en Matplotlib para crear gráficos estadísticos, mapas de calor, contornos y visualizaciones especializadas.

Índice

Histogramas y Distribuciones

Los histogramas son esenciales para visualizar distribuciones de datos.

Histograma Básico

import matplotlib.pyplot as plt
import numpy as np

# Generar datos con distribución normal
np.random.seed(42)
datos = np.random.normal(0, 1, 1000)

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

# Crear histograma
plt.hist(datos, bins=30, alpha=0.7, color='skyblue', edgecolor='black', linewidth=1)

plt.xlabel('Valor', fontsize=12)
plt.ylabel('Frecuencia', fontsize=12)
plt.title('Histograma de Distribución Normal', fontsize=14, fontweight='bold')
plt.grid(True, alpha=0.3)

# Agregar línea de densidad
from scipy import stats
x_densidad = np.linspace(min(datos), max(datos), 100)
densidad = stats.norm.pdf(x_densidad, np.mean(datos), np.std(datos))
plt.plot(x_densidad, densidad * len(datos) * (max(datos) - min(datos)) / 30,
         'r-', linewidth=2, label='Densidad teórica')

plt.legend()
plt.show()

Múltiples Histogramas

import matplotlib.pyplot as plt
import numpy as np

# Generar diferentes distribuciones
np.random.seed(42)
datos1 = np.random.normal(0, 1, 1000)
datos2 = np.random.normal(2, 1.5, 1000)
datos3 = np.random.exponential(1, 1000)

plt.figure(figsize=(15, 10))

# Subplot 1: Histogramas superpuestos
plt.subplot(2, 2, 1)
plt.hist(datos1, bins=30, alpha=0.5, label='Normal(0,1)', color='blue', density=True)
plt.hist(datos2, bins=30, alpha=0.5, label='Normal(2,1.5)', color='red', density=True)
plt.hist(datos3, bins=30, alpha=0.5, label='Exponencial(1)', color='green', density=True)
plt.xlabel('Valor')
plt.ylabel('Densidad')
plt.title('Histogramas Superpuestos')
plt.legend()
plt.grid(True, alpha=0.3)

# Subplot 2: Histogramas apilados
plt.subplot(2, 2, 2)
plt.hist([datos1, datos2, datos3], bins=30, alpha=0.7,
         label=['Normal 1', 'Normal 2', 'Exponencial'], stacked=True)
plt.xlabel('Valor')
plt.ylabel('Frecuencia')
plt.title('Histogramas Apilados')
plt.legend()
plt.grid(True, alpha=0.3)

# Subplot 3: Histogramas por grupos
plt.subplot(2, 2, 3)
bins = np.linspace(-3, 6, 30)
plt.hist(datos1, bins=bins, alpha=0.7, label='Grupo A', color='lightblue')
plt.hist(datos2, bins=bins, alpha=0.7, label='Grupo B', color='lightcoral')
plt.xlabel('Valor')
plt.ylabel('Frecuencia')
plt.title('Comparación por Grupos')
plt.legend()
plt.grid(True, alpha=0.3)

# Subplot 4: Histograma 2D
plt.subplot(2, 2, 4)
plt.hist2d(datos1, datos2, bins=30, cmap='viridis', alpha=0.8)
plt.colorbar(label='Frecuencia')
plt.xlabel('Variable X')
plt.ylabel('Variable Y')
plt.title('Histograma 2D')
plt.grid(True, alpha=0.3)

plt.tight_layout()
plt.show()

Histogramas con Estadísticas

import matplotlib.pyplot as plt
import numpy as np

# Datos de ejemplo
np.random.seed(42)
datos = np.random.normal(50, 15, 1000)

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

# Crear histograma
n, bins, patches = plt.hist(datos, bins=30, alpha=0.7, color='skyblue', edgecolor='black')

# Calcular estadísticas
media = np.mean(datos)
mediana = np.median(datos)
desvio = np.std(datos)
q25, q75 = np.percentile(datos, [25, 75])

# Líneas de referencia
plt.axvline(media, color='red', linestyle='--', linewidth=2, label='.1f')
plt.axvline(mediana, color='green', linestyle='--', linewidth=2, label='.1f')
plt.axvline(media + desvio, color='orange', linestyle=':', linewidth=2, label='.1f')
plt.axvline(media - desvio, color='orange', linestyle=':', linewidth=2, label='.1f')

# Relleno para el IQR
plt.axvspan(q25, q75, alpha=0.2, color='yellow', label='.1f')

plt.xlabel('Valor', fontsize=12)
plt.ylabel('Frecuencia', fontsize=12)
plt.title('Histograma con Estadísticas Descriptivas', fontsize=14, fontweight='bold')
plt.legend()
plt.grid(True, alpha=0.3)

# Agregar texto con estadísticas
stats_text = ".1f"".1f"".1f"".1f"".1f"f"""
Estadísticas:
Media: {media:.1f}
Mediana: {mediana:.1f}
Desvío: {desvio:.1f}
Q25: {q25:.1f}
Q75: {q75:.1f}
IQR: {q75-q25:.1f}
"""

plt.text(0.02, 0.98, stats_text, transform=plt.gca().transAxes,
         fontsize=10, verticalalignment='top',
         bbox=dict(boxstyle='round,pad=0.5', facecolor='lightgray', alpha=0.8))

plt.show()

Histogramas y diagramas estadísticos Fig. 1: Histogramas, box plots y violin plots para análisis estadístico

Diagramas de Caja (Box Plots)

Los diagramas de caja son excelentes para comparar distribuciones y detectar outliers.

Box Plot Básico

import matplotlib.pyplot as plt
import numpy as np

# Generar datos
np.random.seed(42)
datos1 = np.random.normal(50, 10, 200)
datos2 = np.random.normal(60, 15, 200)
datos3 = np.random.normal(45, 8, 200)

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

# Crear box plot
bp = plt.boxplot([datos1, datos2, datos3],
                 labels=['Grupo A', 'Grupo B', 'Grupo C'],
                 patch_artist=True,
                 boxprops=dict(facecolor='lightblue', color='blue'),
                 medianprops=dict(color='red', linewidth=2),
                 whiskerprops=dict(color='blue', linewidth=1.5),
                 capprops=dict(color='blue', linewidth=1.5),
                 flierprops=dict(marker='o', markerfacecolor='red', markersize=5, alpha=0.6))

plt.ylabel('Valor', fontsize=12)
plt.title('Diagramas de Caja Comparativos', fontsize=14, fontweight='bold')
plt.grid(True, alpha=0.3, axis='y')

# Agregar valores estadísticos
for i, datos in enumerate([datos1, datos2, datos3], 1):
    q1, mediana, q3 = np.percentile(datos, [25, 50, 75])
    plt.text(i, mediana, '.1f', ha='center', va='bottom',
             fontsize=9, fontweight='bold', color='red')

plt.show()

Box Plots Horizontales y Personalizados

import matplotlib.pyplot as plt
import numpy as np

# Datos de diferentes categorías
categorias = ['Producto A', 'Producto B', 'Producto C', 'Producto D']
datos = [
    np.random.normal(100, 20, 100),
    np.random.normal(120, 25, 100),
    np.random.normal(90, 15, 100),
    np.random.normal(110, 30, 100)
]

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

# Box plot horizontal
plt.subplot(2, 1, 1)
bp = plt.boxplot(datos, vert=False, labels=categorias, patch_artist=True)

# Personalizar colores
colores = ['lightblue', 'lightgreen', 'lightcoral', 'lightyellow']
for patch, color in zip(bp['boxes'], colores):
    patch.set_facecolor(color)
    patch.set_alpha(0.7)

plt.title('Box Plots Horizontales', fontsize=14, fontweight='bold')
plt.grid(True, alpha=0.3, axis='x')

# Box plot con outliers destacados
plt.subplot(2, 1, 2)

# Agregar algunos outliers extremos
datos_con_outliers = datos.copy()
datos_con_outliers[0] = np.append(datos_con_outliers[0], [200, -10])  # Outliers en Producto A

bp2 = plt.boxplot(datos_con_outliers, labels=categorias, patch_artist=True,
                  flierprops=dict(marker='o', markerfacecolor='red', markersize=8,
                                markeredgecolor='black', alpha=0.8))

# Colores para boxes
for patch in bp2['boxes']:
    patch.set_facecolor('lightblue')
    patch.set_alpha(0.7)

plt.title('Box Plots con Outliers Destacados', fontsize=14, fontweight='bold')
plt.ylabel('Valor', fontsize=12)
plt.grid(True, alpha=0.3, axis='y')

plt.tight_layout()
plt.show()

Box Plots Agrupados

import matplotlib.pyplot as plt
import numpy as np

# Datos de múltiples grupos y condiciones
np.random.seed(42)
grupos = ['Control', 'Tratamiento A', 'Tratamiento B']
condiciones = ['Antes', 'Después']

datos = {}
for grupo in grupos:
    for condicion in condiciones:
        if grupo == 'Control':
            base = 50
        elif grupo == 'Tratamiento A':
            base = 60
        else:
            base = 55

        if condicion == 'Después':
            base += np.random.choice([-10, 0, 10, 20])

        datos[f'{grupo}_{condicion}'] = np.random.normal(base, 8, 50)

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

# Preparar datos para box plot agrupado
etiquetas = []
datos_plot = []

for grupo in grupos:
    for condicion in condiciones:
        etiquetas.append(f'{grupo}\n{condicion}')
        datos_plot.append(datos[f'{grupo}_{condicion}'])

# Crear box plot agrupado
positions = np.arange(len(etiquetas))
bp = plt.boxplot(datos_plot, positions=positions, widths=0.6, patch_artist=True)

# Colores alternados para grupos
colores = ['lightblue', 'lightblue', 'lightgreen', 'lightgreen', 'lightcoral', 'lightcoral']
for patch, color in zip(bp['boxes'], colores):
    patch.set_facecolor(color)
    patch.set_alpha(0.7)

# Líneas separadoras entre grupos
for i in [1.5, 3.5]:
    plt.axvline(i, color='gray', linestyle='--', alpha=0.5)

plt.xticks(positions, etiquetas, fontsize=10)
plt.ylabel('Puntuación', fontsize=12)
plt.title('Box Plots Agrupados: Efecto de Tratamientos', fontsize=14, fontweight='bold')
plt.grid(True, alpha=0.3, axis='y')

# Leyenda
plt.legend([plt.Rectangle((0,0),1,1, facecolor='lightblue', alpha=0.7),
           plt.Rectangle((0,0),1,1, facecolor='lightgreen', alpha=0.7),
           plt.Rectangle((0,0),1,1, facecolor='lightcoral', alpha=0.7)],
          ['Control', 'Tratamiento A', 'Tratamiento B'],
          title='Grupos', bbox_to_anchor=(1.05, 1), loc='upper left')

plt.tight_layout()
plt.show()

Diagramas de Violín

Los diagramas de violín combinan box plots con estimaciones de densidad kernel.

Violin Plot Básico

import matplotlib.pyplot as plt
import numpy as np

# Datos de ejemplo
np.random.seed(42)
datos1 = np.random.normal(50, 10, 200)
datos2 = np.random.normal(60, 15, 200)
datos3 = np.random.normal(45, 8, 200)

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

# Crear violin plot
parts = plt.violinplot([datos1, datos2, datos3],
                      showmeans=True, showmedians=True, showextrema=True)

# Personalizar colores
for pc in parts['bodies']:
    pc.set_facecolor('lightblue')
    pc.set_edgecolor('blue')
    pc.set_alpha(0.7)

# Personalizar elementos
parts['cmeans'].set_color('red')
parts['cmedians'].set_color('green')
parts['cmins'].set_color('purple')
parts['cmaxes'].set_color('purple')

plt.xticks([1, 2, 3], ['Grupo A', 'Grupo B', 'Grupo C'])
plt.ylabel('Valor', fontsize=12)
plt.title('Diagramas de Violín', fontsize=14, fontweight='bold')
plt.grid(True, alpha=0.3, axis='y')

# Leyenda
plt.legend([plt.Line2D([0], [0], color='red', linewidth=2),
           plt.Line2D([0], [0], color='green', linewidth=2),
           plt.Line2D([0], [0], color='purple', linewidth=2)],
          ['Media', 'Mediana', 'Mín/Máx'],
          bbox_to_anchor=(1.05, 1), loc='upper left')

plt.show()

Violin Plots con Box Plots

import matplotlib.pyplot as plt
import numpy as np

# Datos
np.random.seed(42)
grupos = ['A', 'B', 'C', 'D']
datos = [np.random.normal(i*10 + 50, 5 + i, 100) for i in range(4)]

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

# Crear violin plot
violin_parts = plt.violinplot(datos, positions=range(len(grupos)),
                             showmeans=True, showmedians=True)

# Personalizar violines
for i, pc in enumerate(violin_parts['bodies']):
    pc.set_facecolor(plt.cm.viridis(i / len(grupos)))
    pc.set_edgecolor('black')
    pc.set_alpha(0.7)

# Agregar box plots encima
box_parts = plt.boxplot(datos, positions=range(len(grupos)),
                       widths=0.1, patch_artist=True,
                       boxprops=dict(facecolor='white', alpha=0.8),
                       medianprops=dict(color='red'))

plt.xticks(range(len(grupos)), grupos)
plt.xlabel('Grupos', fontsize=12)
plt.ylabel('Valor', fontsize=12)
plt.title('Violin Plots con Box Plots Integrados', fontsize=14, fontweight='bold')
plt.grid(True, alpha=0.3, axis='y')

plt.show()

Mapas de Calor

Los mapas de calor son ideales para visualizar matrices de datos y correlaciones.

Heatmap Básico

import matplotlib.pyplot as plt
import numpy as np

# Crear matriz de datos
np.random.seed(42)
datos = np.random.rand(10, 10)

plt.figure(figsize=(10, 8))

# Crear heatmap
im = plt.imshow(datos, cmap='viridis', aspect='auto')

# Agregar barra de colores
cbar = plt.colorbar(im, shrink=0.8, aspect=20)
cbar.set_label('Valor', fontsize=12)

plt.xlabel('Columna', fontsize=12)
plt.ylabel('Fila', fontsize=12)
plt.title('Mapa de Calor Básico', fontsize=14, fontweight='bold')

# Agregar valores en las celdas
for i in range(datos.shape[0]):
    for j in range(datos.shape[1]):
        plt.text(j, i, '.2f', ha='center', va='center',
                fontsize=8, color='white' if datos[i, j] > 0.5 else 'black')

plt.show()

Heatmap de Correlación

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

# Simular datos de diferentes variables
np.random.seed(42)
n = 100
datos = {
    'Altura': np.random.normal(170, 10, n),
    'Peso': np.random.normal(70, 15, n),
    'Edad': np.random.normal(30, 8, n),
    'Ingresos': np.random.normal(50000, 20000, n),
    'Educación': np.random.normal(12, 3, n)
}

df = pd.DataFrame(datos)

# Calcular matriz de correlación
corr_matrix = df.corr()

plt.figure(figsize=(10, 8))

# Crear heatmap de correlación
mask = np.triu(np.ones_like(corr_matrix, dtype=bool))  # Máscara para triángulo superior
im = plt.imshow(corr_matrix, cmap='RdYlBu_r', vmin=-1, vmax=1)

# Agregar valores
for i in range(len(corr_matrix)):
    for j in range(len(corr_matrix)):
        if not mask[i, j]:  # Solo mostrar triángulo inferior
            plt.text(j, i, '.2f', ha='center', va='center',
                    fontsize=10, fontweight='bold',
                    color='white' if abs(corr_matrix.iloc[i, j]) > 0.5 else 'black')

# Configurar ejes
plt.xticks(range(len(corr_matrix)), corr_matrix.columns, rotation=45, ha='right')
plt.yticks(range(len(corr_matrix)), corr_matrix.index)

# Barra de colores
cbar = plt.colorbar(im, shrink=0.8, aspect=20)
cbar.set_label('Coeficiente de Correlación', fontsize=12)

plt.title('Matriz de Correlación', fontsize=14, fontweight='bold')
plt.tight_layout()

plt.show()

Heatmap con Anotaciones Personalizadas

import matplotlib.pyplot as plt
import numpy as np

# Crear datos más complejos
np.random.seed(42)
filas = ['Producto A', 'Producto B', 'Producto C', 'Producto D', 'Producto E']
columnas = ['Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun']
ventas = np.random.randint(100, 1000, (len(filas), len(columnas)))

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

# Crear heatmap
im = plt.imshow(ventas, cmap='YlOrRd', aspect='auto')

# Barra de colores
cbar = plt.colorbar(im, shrink=0.8, aspect=15)
cbar.set_label('Ventas ($)', fontsize=12)

# Configurar ejes
plt.xticks(range(len(columnas)), columnas, fontsize=10)
plt.yticks(range(len(filas)), filas, fontsize=10)

plt.xlabel('Mes', fontsize=12)
plt.ylabel('Producto', fontsize=12)
plt.title('Mapa de Calor de Ventas por Producto y Mes', fontsize=14, fontweight='bold')

# Agregar valores con formato condicional
for i in range(len(filas)):
    for j in range(len(columnas)):
        valor = ventas[i, j]
        color = 'white' if valor > 600 else 'black'
        plt.text(j, i, f'${valor}', ha='center', va='center',
                fontsize=9, fontweight='bold', color=color)

# Líneas de cuadrícula
plt.grid(False)  # Desactivar grid automático
for i in range(len(filas)):
    plt.axhline(i - 0.5, color='white', linewidth=1)
for j in range(len(columnas)):
    plt.axvline(j - 0.5, color='white', linewidth=1)

plt.tight_layout()
plt.show()

Gráficos de Contorno

Los gráficos de contorno muestran líneas de nivel en datos tridimensionales.

Contorno Básico

import matplotlib.pyplot as plt
import numpy as np

# Crear datos 3D
x = np.linspace(-3, 3, 100)
y = np.linspace(-3, 3, 100)
X, Y = np.meshgrid(x, y)
Z = np.sin(X) * np.cos(Y)

plt.figure(figsize=(15, 10))

# Gráfico de contorno
plt.subplot(2, 2, 1)
cs = plt.contour(X, Y, Z, levels=15, cmap='viridis')
plt.clabel(cs, inline=True, fontsize=8)
plt.xlabel('X')
plt.ylabel('Y')
plt.title('Gráfico de Contorno')
plt.colorbar(cs, shrink=0.8)
plt.grid(True, alpha=0.3)

# Gráfico de contorno relleno
plt.subplot(2, 2, 2)
csf = plt.contourf(X, Y, Z, levels=20, cmap='RdYlBu')
plt.colorbar(csf, shrink=0.8)
plt.xlabel('X')
plt.ylabel('Y')
plt.title('Contorno Relleno')

# Contorno con etiquetas personalizadas
plt.subplot(2, 2, 3)
cs3 = plt.contour(X, Y, Z, levels=np.linspace(-1, 1, 11), colors='black', linewidths=0.5)
plt.clabel(cs3, inline=True, fontsize=8, fmt='%.1f')
plt.contourf(X, Y, Z, levels=np.linspace(-1, 1, 11), cmap='RdYlBu', alpha=0.3)
plt.xlabel('X')
plt.ylabel('Y')
plt.title('Contorno con Etiquetas')
plt.grid(True, alpha=0.3)

# Contorno 3D
from mpl_toolkits.mplot3d import Axes3D
ax = plt.subplot(2, 2, 4, projection='3d')
surf = ax.plot_surface(X, Y, Z, cmap='viridis', alpha=0.8)
ax.contour(X, Y, Z, levels=10, cmap='viridis', offset=-2)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.set_title('Contorno 3D')
plt.colorbar(surf, ax=ax, shrink=0.6, aspect=10)

plt.tight_layout()
plt.show()

Gráficos Polares

Los gráficos polares son útiles para datos con dirección o ángulo.

Gráfico Polar Básico

import matplotlib.pyplot as plt
import numpy as np

# Datos polares
theta = np.linspace(0, 2*np.pi, 100)
r = 2 * np.sin(4 * theta)

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

# Gráfico polar
ax = plt.subplot(2, 2, 1, polar=True)
ax.plot(theta, r, 'b-', linewidth=2)
ax.set_title('Rosa Polar', fontsize=12, fontweight='bold')
ax.grid(True, alpha=0.3)

# Múltiples funciones polares
ax2 = plt.subplot(2, 2, 2, polar=True)
r1 = 1 + np.cos(theta)
r2 = 1 + 0.5 * np.cos(2*theta)
r3 = 1 + 0.3 * np.cos(3*theta)

ax2.plot(theta, r1, 'r-', label='n=1', linewidth=2)
ax2.plot(theta, r2, 'g-', label='n=2', linewidth=2)
ax2.plot(theta, r3, 'b-', label='n=3', linewidth=2)
ax2.set_title('Funciones Polares', fontsize=12, fontweight='bold')
ax2.legend()
ax2.grid(True, alpha=0.3)

# Datos direccionales (viento)
ax3 = plt.subplot(2, 2, 3, polar=True)
np.random.seed(42)
direcciones = np.random.uniform(0, 2*np.pi, 50)
velocidades = np.random.uniform(0, 10, 50)

ax3.scatter(direcciones, velocidades, c=velocidades, cmap='viridis', s=50, alpha=0.7)
ax3.set_title('Dirección y Velocidad del Viento', fontsize=12, fontweight='bold')
ax3.set_rlabel_position(90)
ax3.grid(True, alpha=0.3)

# Radar chart
ax4 = plt.subplot(2, 2, 4, polar=True)
categorias = ['Fuerza', 'Velocidad', 'Precisión', 'Resistencia', 'Técnica']
valores = [8, 7, 9, 6, 8]

# Cerrar el polígono
angulos = np.linspace(0, 2*np.pi, len(categorias), endpoint=False).tolist()
valores += valores[:1]
angulos += angulos[:1]

ax4.plot(angulos, valores, 'o-', linewidth=2, color='red', markersize=8)
ax4.fill(angulos, valores, alpha=0.25, color='red')
ax4.set_xticks(angulos[:-1])
ax4.set_xticklabels(categorias)
ax4.set_ylim(0, 10)
ax4.set_title('Gráfico Radar', fontsize=12, fontweight='bold')
ax4.grid(True, alpha=0.3)

plt.tight_layout()
plt.show()

Barras de Error

Las barras de error muestran la incertidumbre en las mediciones.

Barras de Error Básicas

import matplotlib.pyplot as plt
import numpy as np

# Datos con incertidumbre
x = np.arange(5)
y = [2, 3, 1, 4, 2.5]
y_err = [0.2, 0.3, 0.1, 0.4, 0.2]  # Error en Y
x_err = [0.1, 0.1, 0.1, 0.1, 0.1]  # Error en X

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

# Barras de error en Y
plt.subplot(2, 2, 1)
plt.errorbar(x, y, yerr=y_err, fmt='o-', capsize=5, capthick=2,
             elinewidth=2, markersize=8, color='blue')
plt.xlabel('X')
plt.ylabel('Y')
plt.title('Barras de Error en Y')
plt.grid(True, alpha=0.3)

# Barras de error en X e Y
plt.subplot(2, 2, 2)
plt.errorbar(x, y, xerr=x_err, yerr=y_err, fmt='s-', capsize=3,
             color='red', ecolor='orange', linewidth=2)
plt.xlabel('X')
plt.ylabel('Y')
plt.title('Barras de Error en X e Y')
plt.grid(True, alpha=0.3)

# Barras de error con diferentes estilos
plt.subplot(2, 2, 3)
plt.errorbar(x, y, yerr=y_err, fmt='o', capsize=5, capthick=1,
             elinewidth=1, markersize=6, color='green', alpha=0.7)
plt.errorbar(x, np.array(y) + 1, yerr=y_err, fmt='s', capsize=3,
             elinewidth=2, markersize=6, color='purple', alpha=0.7)
plt.xlabel('X')
plt.ylabel('Y')
plt.title('Múltiples Series con Barras de Error')
plt.legend(['Serie 1', 'Serie 2'])
plt.grid(True, alpha=0.3)

# Barras de error en barras verticales
plt.subplot(2, 2, 4)
bars = plt.bar(x, y, yerr=y_err, capsize=5, color='lightblue',
               edgecolor='blue', linewidth=1, alpha=0.7)
plt.xlabel('Categoría')
plt.ylabel('Valor')
plt.title('Barras con Error')
plt.grid(True, alpha=0.3, axis='y')

plt.tight_layout()
plt.show()

Gráficos de Área Apilada

Los gráficos de área apilada muestran la contribución de diferentes componentes a un total.

Área Apilada Básica

import matplotlib.pyplot as plt
import numpy as np

# Datos de ventas por categoría
meses = np.arange(1, 13)
ventas_A = np.array([120, 150, 180, 200, 250, 300, 280, 320, 350, 380, 400, 420])
ventas_B = np.array([100, 120, 140, 160, 180, 200, 220, 240, 260, 280, 300, 320])
ventas_C = np.array([80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190])

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

# Gráfico de área apilada
plt.stackplot(meses, ventas_A, ventas_B, ventas_C,
              labels=['Producto A', 'Producto B', 'Producto C'],
              colors=['lightblue', 'lightgreen', 'lightcoral'],
              alpha=0.8)

plt.xlabel('Mes', fontsize=12)
plt.ylabel('Ventas ($)', fontsize=12)
plt.title('Ventas por Producto - Área Apilada', fontsize=14, fontweight='bold')
plt.legend(loc='upper left')
plt.grid(True, alpha=0.3)

# Agregar línea del total
total = ventas_A + ventas_B + ventas_C
plt.plot(meses, total, 'k-', linewidth=2, label='Total')
plt.legend()

plt.xticks(meses, ['Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun',
                   'Jul', 'Ago', 'Sep', 'Oct', 'Nov', 'Dic'], rotation=45)

plt.tight_layout()
plt.show()

Matrices de Dispersión

Las matrices de dispersión muestran relaciones entre múltiples variables.

Scatter Matrix Básica

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

# Crear datos
np.random.seed(42)
n = 100
datos = {
    'Altura': np.random.normal(170, 10, n),
    'Peso': np.random.normal(70, 15, n),
    'Edad': np.random.normal(30, 8, n),
    'Ingresos': np.random.normal(50000, 20000, n)
}

df = pd.DataFrame(datos)

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

# Crear scatter matrix manualmente
variables = list(datos.keys())
n_vars = len(variables)

for i in range(n_vars):
    for j in range(n_vars):
        plt.subplot(n_vars, n_vars, i*n_vars + j + 1)

        if i == j:
            # Diagonal: histogramas
            plt.hist(df[variables[i]], bins=15, alpha=0.7, color='skyblue', edgecolor='black')
            plt.title(f'{variables[i]}', fontsize=10)
        else:
            # Off-diagonal: scatter plots
            plt.scatter(df[variables[j]], df[variables[i]], alpha=0.6, s=20, color='blue')
            if i == n_vars-1:  # Última fila
                plt.xlabel(variables[j], fontsize=8)
            if j == 0:  # Primera columna
                plt.ylabel(variables[i], fontsize=8)

        # Ocultar ticks para claridad
        if i < n_vars-1:
            plt.xticks([])
        if j > 0:
            plt.yticks([])

plt.suptitle('Matriz de Dispersión', fontsize=14, fontweight='bold')
plt.tight_layout()
plt.show()

Visualizaciones Estadísticas Avanzadas

Gráfico Q-Q (Quantile-Quantile)

import matplotlib.pyplot as plt
import numpy as np
from scipy import stats

# Datos
np.random.seed(42)
datos_normales = np.random.normal(0, 1, 200)
datos_exponenciales = np.random.exponential(1, 200)

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

# Q-Q plot para datos normales
plt.subplot(1, 2, 1)
stats.probplot(datos_normales, dist="norm", plot=plt)
plt.title('Q-Q Plot: Datos Normales vs Normal Teórica')
plt.grid(True, alpha=0.3)

# Q-Q plot para datos exponenciales
plt.subplot(1, 2, 2)
stats.probplot(datos_exponenciales, dist="expon", plot=plt)
plt.title('Q-Q Plot: Datos Exponenciales vs Exponencial Teórica')
plt.grid(True, alpha=0.3)

plt.tight_layout()
plt.show()

Gráfico de Andrews

import matplotlib.pyplot as plt
import numpy as np
from pandas.plotting import andrews_curves
import pandas as pd

# Crear datos de ejemplo
np.random.seed(42)
n = 50
datos = {
    'Grupo': np.random.choice(['A', 'B', 'C'], n),
    'Var1': np.random.normal(0, 1, n),
    'Var2': np.random.normal(2, 1, n),
    'Var3': np.random.normal(-1, 1, n),
    'Var4': np.random.normal(1, 2, n)
}

df = pd.DataFrame(datos)

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

# Gráfico de Andrews
andrews_curves(df, 'Grupo', colormap='viridis')

plt.title('Curvas de Andrews por Grupo', fontsize=14, fontweight='bold')
plt.xlabel('t', fontsize=12)
plt.ylabel('f(t)', fontsize=12)
plt.grid(True, alpha=0.3)
plt.legend(title='Grupo')

plt.show()

¡Has dominado los gráficos avanzados de Matplotlib! Ahora puedes crear visualizaciones estadísticas complejas y mapas de calor profesionales.

En el próximo tutorial aprenderás sobre Gráficos 3D para crear visualizaciones tridimensionales impactantes.

Toca los botones para interactuar

Comentarios

Comentarios

Inicia sesión para dejar un comentario.

No hay comentarios aún

Sé el primero en comentar este tutorial.

Tutoriales Relacionados

Descubre más tutoriales relacionados que podrían ser de tu interés

Imagen destacada del tutorial relacionado: Gráficos 3D con Matplotlib: Visualización Tridimensional
Matplotlib

Gráficos 3D con Matplotlib: Visualización Tridimensional

Aprende a crear gráficos 3D impactantes con Matplotlib: superficies, dispersión 3D, líneas 3D, barras 3D y animaciones tridimensionales.

José Elías Romero Guanipa
01 Sep 2025
Imagen destacada del tutorial relacionado: Gráficos Básicos con Matplotlib: Tipos de Gráficos Esenciales
Matplotlib

Gráficos Básicos con Matplotlib: Tipos de Gráficos Esenciales

Aprende a crear los tipos de gráficos más comunes con Matplotlib: líneas, dispersión, barras, áreas y más con ejemplos prácticos.

José Elías Romero Guanipa
01 Sep 2025
Imagen destacada del tutorial relacionado: Introducción a Matplotlib: Visualización de Datos en Python
Matplotlib

Introducción a Matplotlib: Visualización de Datos en Python

Aprende los fundamentos de Matplotlib, la biblioteca más popular para crear gráficos y visualizaciones en Python. Desde la instalación hasta tu primer gráfico.

José Elías Romero Guanipa
01 Sep 2025
Imagen destacada del tutorial relacionado: Personalización de Gráficos con Matplotlib: Colores, Estilos y Temas
Matplotlib

Personalización de Gráficos con Matplotlib: Colores, Estilos y Temas

Aprende a personalizar completamente tus gráficos con Matplotlib: colores, estilos, fuentes, leyendas, anotaciones y temas profesionales.

José Elías Romero Guanipa
01 Sep 2025
Imagen destacada del tutorial relacionado: Subplots y Múltiples Figuras con Matplotlib: Layouts Complejos
Matplotlib

Subplots y Múltiples Figuras con Matplotlib: Layouts Complejos

Aprende a crear layouts complejos con múltiples gráficos usando subplots, GridSpec y técnicas avanzadas de organización visual.

José Elías Romero Guanipa
01 Sep 2025
Foto de perfil del autor José Elías Romero Guanipa
José Elías Romero Guanipa
Autor

🌟 Nube de Etiquetas

Descubre temas populares en nuestros tutoriales

python
python 25 tutoriales
ciencia de datos
ciencia de datos 8 tutoriales
matplotlib
matplotlib 7 tutoriales
pandas
pandas 6 tutoriales
visualizacion
visualizacion 6 tutoriales
principiante
principiante 5 tutoriales
numpy
numpy 5 tutoriales
estadistica
estadistica 4 tutoriales
bases de datos
bases de datos 4 tutoriales
dataframe
dataframe 4 tutoriales
csv
csv 3 tutoriales
json
json 3 tutoriales
poo
poo 3 tutoriales
machine learning
machine learning 3 tutoriales
patrones diseño
patrones diseño 3 tutoriales
rendimiento
rendimiento 3 tutoriales
mysql
mysql 3 tutoriales
postgresql
postgresql 3 tutoriales
analisis de datos
analisis de datos 3 tutoriales
graficos
graficos 3 tutoriales
excepciones
excepciones 2 tutoriales
algoritmos
algoritmos 2 tutoriales
estructuras datos
estructuras datos 2 tutoriales
programación
programación 2 tutoriales
colaboracion
colaboracion 2 tutoriales

Las etiquetas más grandes y brillantes aparecen en más tutoriales

logo logo

©2024 ViveBTC