Matplotlib: Fundamentos de Graficos en Python
El ABC de la VisualizacionMatplotlib es la libreria base de visualizacion en Python. Seaborn, Plotly y otras se construyen sobre ella. Dominar Matplotlib te da control total sobre cada aspecto de tus graficos.
La Anatomia de un Grafico
import matplotlib.pyplot as plt
import numpy as np
# Figure: el lienzo completo
# Axes: un grafico individual dentro del lienzo
# Artist: todo lo visible (lineas, texto, leyendas, etc.)
fig, ax = plt.subplots(figsize=(10, 6))
# Datos
meses = ['Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun']
ventas = [120, 135, 98, 145, 167, 189]
# Grafico de barras
bars = ax.bar(meses, ventas, color='#2196F3', edgecolor='white', width=0.6)
# Personalizar
ax.set_title('Ventas Mensuales 2025', fontsize=16, fontweight='bold', pad=15)
ax.set_xlabel('Mes', fontsize=12)
ax.set_ylabel('Ventas (miles USD)', fontsize=12)
ax.set_ylim(0, 220)
# Agregar valores encima de las barras
for bar, valor in zip(bars, ventas):
ax.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 3,
f'${valor}k', ha='center', fontsize=10, fontweight='bold')
# Grid sutil
ax.grid(axis='y', alpha=0.3)
ax.set_axisbelow(True)
# Linea de objetivo
ax.axhline(y=150, color='red', linestyle='--', alpha=0.7, label='Objetivo: $150k')
ax.legend()
plt.tight_layout()
plt.savefig('ventas_mensuales.png', dpi=150, bbox_inches='tight')
plt.show()
Tipos de Graficos Esenciales
Grafico de lineas (series temporales)
import pandas as pd
np.random.seed(42)
fechas = pd.date_range('2025-01-01', periods=365, freq='D')
ventas = 100 + np.cumsum(np.random.randn(365) * 2)
fig, ax = plt.subplots(figsize=(12, 5))
ax.plot(fechas, ventas, color='#1976D2', linewidth=1.5)
ax.fill_between(fechas, ventas, alpha=0.1, color='#1976D2')
ax.set_title('Ventas Acumuladas 2025')
ax.set_xlabel('Fecha')
ax.set_ylabel('Ventas acumuladas')
plt.tight_layout()
plt.show()
Scatter plot (correlacion)
np.random.seed(42)
exp = np.random.randint(0, 25, 100)
sal = 35000 + exp * 2500 + np.random.normal(0, 8000, 100)
fig, ax = plt.subplots(figsize=(8, 6))
scatter = ax.scatter(exp, sal, c=exp, cmap='viridis', alpha=0.6, s=50)
plt.colorbar(scatter, label='Experiencia (anios)')
ax.set_title('Experiencia vs Salario')
ax.set_xlabel('Anios de Experiencia')
ax.set_ylabel('Salario (USD)')
# Linea de tendencia
z = np.polyfit(exp, sal, 1)
p = np.poly1d(z)
ax.plot(sorted(exp), p(sorted(exp)), 'r--', alpha=0.8, label=f'Tendencia: y={z[0]:.0f}x+{z[1]:.0f}')
ax.legend()
plt.tight_layout()
plt.show()
Histograma (distribucion)
np.random.seed(42)
salarios = np.random.lognormal(10.8, 0.5, 1000)
fig, ax = plt.subplots(figsize=(10, 6))
n, bins, patches = ax.hist(salarios, bins=40, edgecolor='white', alpha=0.7, color='#4CAF50')
# Colorear por percentil
for i, (patch, left, right) in enumerate(zip(patches, bins[:-1], bins[1:])):
if right < np.percentile(salarios, 25):
patch.set_facecolor('#FF5722')
elif right > np.percentile(salarios, 75):
patch.set_facecolor('#2196F3')
# Lineas de referencia
ax.axvline(salarios.mean(), color='red', linestyle='--', label=f'Media: ${salarios.mean():,.0f}')
ax.axvline(np.median(salarios), color='blue', linestyle='--', label=f'Mediana: ${np.median(salarios):,.0f}')
ax.set_title('Distribucion de Salarios')
ax.set_xlabel('Salario (USD)')
ax.set_ylabel('Frecuencia')
ax.legend()
plt.tight_layout()
plt.show()
Grafico de torta (proporciones)
categorias = ['Laptops', 'Monitores', 'Teclados', 'Mouse', 'Auriculares']
ventas = [35, 25, 20, 12, 8]
colors = ['#2196F3', '#4CAF50', '#FFC107', '#FF5722', '#9C27B0']
explode = (0.05, 0, 0, 0, 0)
fig, ax = plt.subplots(figsize=(8, 8))
wedges, texts, autotexts = ax.pie(
ventas, labels=categorias, colors=colors, explode=explode,
autopct='%1.1f%%', startangle=90, pctdistance=0.85
)
ax.set_title('Distribucion de Ventas por Categoria', fontsize=14)
plt.tight_layout()
plt.show()
Subplots: Multiples Graficos
np.random.seed(42)
fig, axes = plt.subplots(2, 2, figsize=(14, 10))
fig.suptitle('Dashboard de Ventas', fontsize=16, fontweight='bold')
# 1. Barras
meses = ['Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun']
ventas = [120, 135, 98, 145, 167, 189]
axes[0, 0].bar(meses, ventas, color='#2196F3')
axes[0, 0].set_title('Ventas Mensuales')
axes[0, 0].set_ylabel('Miles USD')
# 2. Lineas
dias = range(1, 31)
ventas_diarias = np.random.randint(80, 200, 30)
axes[0, 1].plot(dias, ventas_diarias, 'o-', color='#4CAF50')
axes[0, 1].set_title('Ventas Diarias (Junio)')
axes[0, 1].set_xlabel('Dia')
# 3. Histograma
montos = np.random.lognormal(5, 1, 500)
axes[1, 0].hist(montos, bins=30, color='#FF9800', edgecolor='white')
axes[1, 0].set_title('Distribucion de Montos')
# 4. Scatter
x = np.random.rand(50) * 100
y = x * 0.8 + np.random.randn(50) * 10
axes[1, 1].scatter(x, y, alpha=0.6, color='#9C27B0')
axes[1, 1].set_title('Gasto Marketing vs Ventas')
plt.tight_layout()
plt.savefig('dashboard.png', dpi=150)
plt.show()
Estilos Profesionales
# Estilos disponibles
print(plt.style.available)
# Aplicar un estilo
plt.style.use('seaborn-v0_8-whitegrid') # Limpio y profesional
# Otras opciones populares: 'ggplot', 'fivethirtyeight', 'dark_background'
# Configuracion global personalizada
plt.rcParams.update({
'font.size': 12,
'figure.figsize': (10, 6),
'axes.grid': True,
'grid.alpha': 0.3
})
Video Recomendado
Matplotlib Tutorial Completo en Espanol
Ejercicio Practico
Crea un notebook 16_matplotlib.ipynb:
- Crea un grafico de barras horizontales con los 10 paises con mayor PIB
- Crea un scatter plot con datos de experiencia vs salario, coloreado por departamento
- Crea un histograma con distribucion de edades de empleados
- Crea un dashboard con 4 subplots mostrando diferentes aspectos de un dataset
- Guarda todos los graficos como PNG de alta resolucion
💡 Concepto Clave
Revisemos los puntos más importantes de esta lección antes de continuar.
Resumen
- fig, ax = plt.subplots(): La forma correcta de crear graficos
- Tipos: bar, plot, scatter, hist, pie
- Personalizar: set_title, set_xlabel, set_ylabel, legend, grid
- Subplots: Multiples graficos en una figura
- Estilos: plt.style.use() para cambiar la apariencia global
- Guardar: plt.savefig() con dpi=150 para alta calidad
🧠 Pon a prueba tu conocimiento
¿Cuál es el aspecto más importante que aprendiste en esta lección?
- Comprendo el concepto principal y puedo explicarlo con mis palabras
- Entiendo cómo aplicarlo en mi situación específica
- Necesito repasar algunas partes antes de continuar
- Quiero ver más ejemplos prácticos del tema
✅ ¡Excelente! Continúa con la siguiente lección para profundizar más.