Domina Matplotlib 📈

Construye visualizaciones profesionales para matemáticas 🧮 y física 🔬 usando la librería de gráficos más popular de Python.

1. Instalación & Importación

Matplotlib se instala vía pip y se importa normalmente como plt. Esta convención se usa en casi todos los libros y tutoriales.

Instalación

pip install matplotlib

Importación

import matplotlib.pyplot as plt
Código 1.1 — Prueba rápida
import matplotlib.pyplot as plt
plt.plot([0,1,2],[0,1,4])
plt.title("¡Tu primer gráfico!")
plt.show()

Tip rápido: ejecuta el código anterior en un entorno interactivo (Jupyter, IPython) para ver el gráfico emergente.

2. Anatomía de Matplotlib

El núcleo de Matplotlib gira en torno a la pareja Figure (fig) y Axes (ax). Una Figure es el lienzo global; los Axes son los sistemas de coordenadas donde dibujas.

Anatomía de Matplotlib: Muestra la jerarquía de Figure, Axes, Axis, Spines, Title, Labels, Ticks y Legend.

Diagrama sugerido de la jerarquía Figure → Axes → Axis/Spines.

Código 2.1 — Crear un lienzo vacío
fig = plt.figure(figsize=(6,4))      # Crea la Figure
ax  = fig.add_subplot(111)          # Añade un Axes (1x1 grid)
ax.set_title("Ejes primarios")
ax.plot([],[])                      # Aún sin datos
plt.show()

📑 Glosario rápido

fig

Lienzo global (puede contener varios Axes).

ax

Sistema de coordenadas donde se dibujan líneas, barras, etc.

subplot

Atajo para crear Axes multipanel en grillas.

Spines

Los bordes del gráfico (superior, inferior, izq., der.).

3. Tipos de Gráficos 🍭

Matplotlib soporta una gran variedad de gráficos. Estos son los más usados:

Línea (plot)

Datos continuos, series temporales.

Barra (bar)

Categorías discretas.

Dispersión (scatter)

Pares (x,y) para correlaciones.

Histograma (hist)

Distribución de frecuencias.

Código 3.1 — Cuatro gráficos en un solo lienzo
import numpy as np
fig, axs = plt.subplots(2, 2, figsize=(8,6))

# 1) Línea
x = np.linspace(0, 2*np.pi, 100)
axs[0,0].plot(x, np.sin(x), color='indigo')
axs[0,0].set_title('Seno')

# 2) Barras
cats = ['A','B','C']
axs[0,1].bar(cats, [3,7,5], color='teal')
axs[0,1].set_title('Barras')

# 3) Dispersión
rng = np.random.default_rng(0)
axs[1,0].scatter(rng.random(50), rng.random(50), c='tomato')
axs[1,0].set_title('Dispersión')

# 4) Histograma
data = rng.normal(size=500)
axs[1,1].hist(data, bins=20, color='goldenrod', edgecolor='white')
axs[1,1].set_title('Histograma')

plt.tight_layout() # Ajusta el espaciado para evitar superposiciones
plt.show()

4. Personalización Básica 🎨

Puedes ajustar prácticamente todo: títulos, ejes, leyendas, estilos de línea, colores…

Código 4.1 — Apariencia a la carta
fig, ax = plt.subplots(figsize=(6,4))
x = np.linspace(0, 2*np.pi, 100) # Definir x si no viene de la sección anterior

ax.plot(x, np.sin(x), label='Seno', linewidth=3, linestyle='--', color='#0ea5e9')
ax.plot(x, np.cos(x), label='Coseno', linewidth=2, linestyle='-.', color='#f97316')

ax.set_title('Funciones trigonométricas', fontsize=16, fontweight='bold')
ax.set_xlabel('x (rad)')
ax.set_ylabel('f(x)')
ax.grid(alpha=0.3)
ax.legend(frameon=False)

# Oculta el spine superior & derecho (estética minimalista)
for sp in ['right','top']:
    ax.spines[sp].set_visible(False)

plt.show()

Usa plt.style.available para ver estilos prehechos. Prueba: plt.style.use('ggplot').

5. El Poder de fig, ax = plt.subplots()

Esta función devuelve la dupla Figure y Axes de forma directa, favoreciendo un código más limpio y explícito. Es la forma recomendada de iniciar tus gráficos.

Explícito

Separa claramente fig y uno o más ax.

Multipanel

Crea grillas al instante (ej: plt.subplots(2,3)).

tight_layout()

Optimiza espacios automáticamente en la figura.

Código 5.1 — Ejemplo con subplots()
# Crear una figura con 1 fila y 2 columnas de subplots
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 4))

# Primer subplot
x = np.linspace(0, 10, 100)
ax1.plot(x, np.sin(x), color='crimson')
ax1.set_title('Seno en ax1')

# Segundo subplot
ax2.plot(x, np.cos(x), color='dodgerblue')
ax2.set_title('Coseno en ax2')

plt.tight_layout() # Importante para que los subplots no se solapen
plt.show()

6. Ejemplos Matemáticos 🧮

Visualizar funciones ayuda a comprender conceptos de cálculo y álgebra.

6.1 — Seno, Coseno y Tangente

import numpy as np # Asegurar que numpy está importado
import matplotlib.pyplot as plt # Asegurar que pyplot está importado

x = np.linspace(0, 2*np.pi, 400)
fig, ax = plt.subplots(figsize=(7,4))
ax.plot(x, np.sin(x), label='sen(x)')
ax.plot(x, np.cos(x), label='cos(x)')
ax.plot(x, np.tan(x), label='tan(x)', alpha=0.4) # Tangente con transparencia
ax.set_ylim(-2,2) # Limitar el eje Y para mejor visualización de tan(x)
ax.legend(loc='upper right')
ax.set_title('Funciones trigonométricas')
ax.grid(True, linestyle=':', alpha=0.5)
plt.show()

6.2 — Derivada Numérica

f  = lambda x: x**3 - 3*x**2 + 2
xp = np.linspace(-1,4,200)
yp = f(xp)

dydx = np.gradient(yp, xp)   # Derivada numérica usando np.gradient

fig, ax = plt.subplots()
ax.plot(xp, yp, label='f(x) = x³-3x²+2')
ax.plot(xp, dydx, label="f'(x) (numérica)", linestyle='--')
ax.set_title('Función y su derivada numérica')
ax.legend()
ax.grid(True, linestyle=':', alpha=0.5)
plt.show()

7. Ejemplos de Física 🔬

7.1 — Movimiento Parabólico

g = 9.81      # Aceleración gravitacional (m/s²)
v0 = 20       # Velocidad inicial (m/s)
angle = 45    # Ángulo de lanzamiento (grados)

theta = np.radians(angle) # Convertir ángulo a radianes

# Tiempo total de vuelo
t_total = 2*v0*np.sin(theta)/g

t = np.linspace(0, t_total, 200) # Vector de tiempo
x_pos = v0*np.cos(theta)*t         # Posición horizontal
y_pos = v0*np.sin(theta)*t - 0.5*g*t**2 # Posición vertical

fig, ax = plt.subplots()
ax.plot(x_pos, y_pos, color='green')
ax.set_xlabel('Distancia Horizontal (m)')
ax.set_ylabel('Altura Vertical (m)')
ax.set_title(f'Trayectoria Parabólica (v₀={v0}m/s, θ={angle}°)')
ax.grid(True, linestyle=':', alpha=0.5)
ax.set_aspect('equal', adjustable='box') # Para que la trayectoria se vea proporcional
plt.show()

7.2 — Onda Senoidal & Superposición

t = np.linspace(0, 2, 1000) # Tiempo de 0 a 2 segundos
wave1 = np.sin(2*np.pi*5*t)     # Onda de 5 Hz
wave2 = 0.5*np.sin(2*np.pi*7*t) # Onda de 7 Hz con mitad de amplitud
superposicion = wave1 + wave2   # Suma de las ondas

fig, ax = plt.subplots(figsize=(8,5))
ax.plot(t, wave1, label='Onda 1 (5Hz)', linestyle=':', alpha=0.7)
ax.plot(t, wave2, label='Onda 2 (7Hz)', linestyle=':', alpha=0.7)
ax.plot(t, superposicion, label='Superposición', color='purple', linewidth=1.5)
ax.set_xlabel('Tiempo (s)')
ax.set_ylabel('Amplitud')
ax.set_title('Interferencia de dos ondas sinusoidales')
ax.legend()
ax.grid(True, linestyle=':', alpha=0.5)
plt.show()

8. Guardar tus Gráficos 💾

Usa fig.savefig() o directamente plt.savefig() antes de plt.show(). Matplotlib infiere el formato por la extensión del archivo (.png, .pdf, .svg, .jpg).

Código 8.1 — Alta resolución para publicaciones
fig, ax = plt.subplots()
ax.plot([0,1,2],[0,1,4], label='Datos de ejemplo')
ax.set_title('Gráfico de Ejemplo para Guardar')
ax.legend()

# Guardar la figura (asegúrate que la carpeta 'assets/images/' exista o cambia la ruta)
# fig.savefig('assets/images/mi_grafico.png', dpi=300, bbox_inches='tight')
# fig.savefig('mi_grafico_vectorial.svg', bbox_inches='tight') # Formato vectorial

# Para demostración, no ejecutaremos savefig aquí para evitar errores de ruta
# print("El gráfico se guardaría con: fig.savefig('nombre_archivo.png', dpi=300)")

plt.show() # show() usualmente limpia la figura, por eso savefig() va antes.

Importante: bbox_inches='tight' ajusta el tamaño de la figura para que todo el contenido (títulos, etiquetas) quepa sin recortes. dpi (dots per inch) controla la resolución para formatos rasterizados como PNG.

9. Sugerencias Avanzadas 🚀

Matplotlib es vasto. Aquí algunas áreas para explorar más a fondo:

10. Personalización Detallada: Dando Vida a tus Gráficos 🎨✨

Crear un gráfico básico es solo el primer paso. El verdadero poder de Matplotlib radica en su increíble capacidad para personalizar cada detalle de tus visualizaciones. Una personalización cuidadosa no solo embellece tus gráficos, sino que los hace mucho más claros y efectivos para comunicar tus hallazgos científicos. ¡Vamos a explorar cómo convertir un gráfico simple en una obra de arte informativa!

10.1 ax.plot(): Dibujando Líneas con Estilo y Precisión

La función ax.plot(x, y, ...) es tu principal herramienta para gráficos de líneas. Además de los datos x e y, puedes controlar cada detalle visual:

  • color (o c): Define el color de la línea (ej: 'blue', 'red', 'green', códigos hexadecimales como '#FF5733', o tuplas RGB/RGBA como (0.1, 0.2, 0.5)).
  • linewidth (o lw): Controla el grosor de la línea (un número flotante, ej: 2.5).
  • linestyle (o ls): Define el estilo de la línea. Opciones comunes:
    • '-' o 'solid': Línea sólida (por defecto).
    • '--' o 'dashed': Línea discontinua.
    • '-.' o 'dashdot': Línea de guion y punto.
    • ':' o 'dotted': Línea punteada.
  • marker: Especifica el símbolo a usar para cada punto de datos (ej: 'o', 's', '^', 'x', '+').
  • markersize (o ms): Tamaño de los marcadores.
  • markerfacecolor (o mfc), markeredgecolor (o mec): Colores del marcador.
  • label: Etiqueta de la línea que se usará en la leyenda del gráfico.
Código 10.1.1 — Personalizando una trayectoria de proyectil (Física)
# (Reutilizando parámetros de la sección 7.1)
g = 9.81; v0 = 30; angulo_grados = 45
theta = np.radians(angulo_grados)
t_vuelo = (2 * v0 * np.sin(theta)) / g
t = np.linspace(0, t_vuelo, 200)
x_proyectil = v0 * np.cos(theta) * t
y_proyectil = v0 * np.sin(theta) * t - 0.5 * g * t**2

fig, ax = plt.subplots(figsize=(8, 5))
ax.plot(x_proyectil, y_proyectil, 
        color='orangered', linewidth=2.5, linestyle='-.', 
        marker='^', markersize=7, markevery=15, 
        markerfacecolor='gold', markeredgecolor='dimgray', 
        label=f'Trayectoria (v0={v0}m/s, θ={angulo_grados}°)')

ax.set_title('Lanzamiento de Proyectil Detallado 🎯', fontsize=16, color='#7f1d1d')
ax.set_xlabel('Distancia Horizontal (m)', fontsize=12, color='#7f1d1d')
ax.set_ylabel('Altura Vertical (m)', fontsize=12, color='#7f1d1d')
ax.grid(True, linestyle=':', alpha=0.6)
ax.legend(fontsize=10)
plt.show()

10.2 ax.legend(): Identificando tus Datos con Leyendas

Esencial cuando graficas múltiples conjuntos de datos. Recuerda usar el argumento label en tus llamadas a plot().

  • loc: Posición ('upper right', 'best', 'center', o un código numérico).
  • frameon: Booleano para mostrar/ocultar el marco.
  • facecolor, edgecolor: Colores del cuadro de la leyenda.
  • fontsize, title, ncol: Para tamaño, título y número de columnas.
Código 10.2.1 — Leyenda para decaimiento exponencial (Física/Matemáticas)
t = np.linspace(0, 5, 100)
N1 = 100 * np.exp(-0.8 * t)
N2 = 100 * np.exp(-0.3 * t)

fig, ax = plt.subplots(figsize=(8, 5))
ax.plot(t, N1, label='Sustancia A (τ ≈ 1.25s)', color='mediumvioletred', lw=2.5)
ax.plot(t, N2, label='Sustancia B (τ ≈ 3.33s)', color='darkslateblue', lw=2.5, ls=':')

ax.legend(loc='center right', fontsize='large', frameon=True, 
          facecolor='#f0f0f0', edgecolor='black', shadow=True, 
          title='Curvas de Decaimiento ⏳', ncol=1)
ax.set_title('Comparación de Tasas de Decaimiento Radiactivo ☢️', fontsize=15, color='#7f1d1d')
ax.set_xlabel('Tiempo (unidades arbitrarias)', fontsize=12, color='#7f1d1d')
ax.set_ylabel('Cantidad de Sustancia (%)', fontsize=12, color='#7f1d1d')
ax.grid(True, linestyle='--', alpha=0.5)
plt.show()

10.3 ax.spines[]: Personalizando los Bordes del Gráfico

Los "spines" son las líneas que enmarcan el área del gráfico. Puedes ocultarlos o moverlos para que se crucen en el origen (0,0).

Código 10.3.1 — Gráfico estilo "científico" con ejes en el origen
x = np.linspace(-2*np.pi, 2*np.pi, 200)
y_sinc = np.sinc(x/np.pi) # Función Sinc normalizada

fig, ax = plt.subplots(figsize=(7,4.5))
ax.plot(x, y_sinc, color='darkcyan', lw=2.5)
ax.set_title('Función Sinc(x/π) - Estilo Científico 📐', fontsize=14, color='#7f1d1d')

ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.spines['left'].set_position('zero')
ax.spines['bottom'].set_position('zero')

ax.set_xlim(-2*np.pi - 0.5, 2*np.pi + 0.5)
ax.set_ylim(-0.4, 1.2)

ax.plot(1, 0, ">k", transform=ax.get_yaxis_transform(), clip_on=False, markersize=7) # Flecha eje X
ax.plot(0, 1, "^k", transform=ax.get_xaxis_transform(), clip_on=False, markersize=7) # Flecha eje Y

ax.set_xticks([-2*np.pi, -np.pi, np.pi, 2*np.pi])
ax.set_xticklabels(['-2π', '-π', 'π', '2π'])
ax.set_yticks([-0.2, 0.5, 1.0])
plt.show()

10.4 ax.set_xlim() y ax.set_ylim(): Definiendo el Rango de los Ejes

Te permiten fijar manualmente los límites inferior y superior para los ejes X e Y.

Código 10.4.1 — Enfocando una sección de una parábola (Matemáticas)
x = np.linspace(-5, 5, 200)
y = (x - 1)**2 # Parábola con vértice en (1,0)

fig, ax = plt.subplots(figsize=(7,5))
ax.plot(x, y, color='forestgreen', label='y = (x-1)²', lw=2)
ax.set_title('Zoom en el Vértice de la Parábola 🔍', fontsize=15, color='#7f1d1d')

ax.set_xlim(0, 2) # Rango de X: de 0 a 2
ax.set_ylim(-0.5, 1.5) # Rango de Y: de -0.5 a 1.5

ax.grid(True, linestyle=':', alpha=0.6)
ax.legend()
ax.axhline(0, color='black', lw=0.5) # Línea del eje X
ax.axvline(1, color='grey', lw=0.5, ls='--') # Línea en el vértice
plt.show()

10.5 set_xticks() y set_xticklabels(): Marcas y Etiquetas a Medida

Controla exactamente dónde aparecen las marcas (ticks) en los ejes y qué texto muestran. Muy útil para representar unidades especiales como múltiplos de $\pi$.

Código 10.5.1 — Gráfico de Coseno con etiquetas de $\pi$ (Matemáticas)
x_rad = np.linspace(0, 2 * np.pi, 200)
y_cos = np.cos(x_rad)

fig, ax = plt.subplots(figsize=(8,4))
ax.plot(x_rad, y_cos, color='mediumpurple', lw=2.5)
ax.set_title('Función Coseno con Eje X en Términos de π 📐', fontsize=15, color='#7f1d1d')

ax.set_xticks([0, np.pi/2, np.pi, 3*np.pi/2, 2*np.pi])
ax.set_xticklabels(['0', r'$\frac{\pi}{2}$', r'$\pi$', r'$\frac{3\pi}{2}$', r'$2\pi$'], fontsize=12)

ax.grid(True, linestyle=':', alpha=0.5)
ax.axhline(0, color='black', lw=0.7)
plt.show()

10.6 ax.set_aspect(): Controlando la Proporción Visual

Controla la relación de aspecto entre las escalas de los ejes X e Y. 'equal' es esencial para que los círculos se vean circulares.

Código 10.6.1 — Círculo perfecto usando 'equal' (Matemáticas/Geometría)
theta_circ = np.linspace(0, 2 * np.pi, 150)
radio_circ = 3
x_circ = radio_circ * np.cos(theta_circ)
y_circ = radio_circ * np.sin(theta_circ)

fig, ax = plt.subplots(figsize=(6,6)) # Figura cuadrada para 'equal'
ax.plot(x_circ, y_circ, color='dodgerblue', lw=3, label=f'Círculo r={radio_circ}')
ax.set_title('Un Círculo Geométricamente Correcto ⭕', fontsize=15, color='#7f1d1d')

ax.set_aspect('equal') # ¡La clave para un círculo perfecto!
ax.grid(True, linestyle=':', alpha=0.5)
ax.axhline(0, color='grey', lw=0.5); ax.axvline(0, color='grey', lw=0.5) # Ejes
ax.legend()
plt.show()

10.7 plt.show(): ¡Que se Muestre el Gráfico!

Esta función renderiza y muestra todos los gráficos configurados. Esencial en scripts.

Código 10.7.1 — Múltiples figuras y plt.show()
# Gráfico 1
plt.figure(1, figsize=(5,3)) 
plt.plot([1,5,2,8], marker='x', color='slateblue')
plt.title("Gráfico Sencillo 1")

# Gráfico 2 (en una nueva figura)
plt.figure(2, figsize=(5,3))
x_exp = np.linspace(0,3,50)
plt.plot(x_exp, np.exp(x_exp), color='teal', ls='--')
plt.title("Función Exponencial (Gráfico 2)")

plt.show() # Muestra ambas figuras configuradas

10.8 ax.grid(): Añadiendo una Rejilla de Referencia

Mejora la legibilidad facilitando la estimación de valores.

  • ax.grid(True): Activa la rejilla principal.
  • which: 'major' (defecto), 'minor', o 'both'.
  • axis: 'x', 'y', o 'both' (defecto).
  • alpha: Transparencia (0.0 a 1.0).
Código 10.8.1 — Gráfico de una función física con rejilla detallada
distancia_r = np.linspace(1, 10, 100)
k_const = 8.9875e9; carga_Q = 1e-6 
campo_E = (k_const * carga_Q) / (distancia_r**2)

fig, ax = plt.subplots(figsize=(8,5))
ax.plot(distancia_r, campo_E, color='firebrick', lw=2)
ax.set_title('Intensidad del Campo Eléctrico vs. Distancia $E = kQ/r^2$ ⚡', fontsize=14, color='#7f1d1d')

ax.grid(which='major', linestyle='-', linewidth='0.6', color='darkgrey', alpha=0.7)
ax.minorticks_on() # Activar ticks menores para la rejilla menor
ax.grid(which='minor', linestyle=':', linewidth='0.4', color='lightgrey', alpha=0.6)

ax.set_yscale('log') # Escala logarítmica en Y
plt.show()

10.9 ax.scatter(): Visualizando Puntos de Datos Individuales

Ideal para mostrar la relación entre dos variables o datos experimentales.

  • s: Tamaño de los marcadores.
  • c: Color (puede ser un array para colores variables, usando `cmap`).
  • alpha: Transparencia.
  • cmap: Mapa de colores si c es numérico (ej. 'viridis', 'plasma').
Código 10.9.1 — Dispersión de datos experimentales (Física/Estadística)
rng = np.random.default_rng(0)
num_datos = 70
voltaje_V = rng.uniform(1, 10, num_datos)
corriente_A = 0.2 * voltaje_V + rng.normal(0, 0.3, num_datos) # Ley de Ohm con ruido
resistencia_calculada = voltaje_V / corriente_A
tamano_puntos = rng.uniform(15, 150, num_datos)

fig, ax = plt.subplots(figsize=(9,6))
dispersion = ax.scatter(voltaje_V, corriente_A, s=tamano_puntos, c=resistencia_calculada, 
                        cmap='plasma', alpha=0.75, edgecolor='black', linewidth=0.6)

ax.set_title('Relación Voltaje-Corriente (Datos Simulados) 💡', fontsize=14, color='#7f1d1d')
cbar = fig.colorbar(dispersion, label='Resistencia Calculada (Ω)')
ax.grid(True, linestyle=':', alpha=0.5)
plt.show()

10.10 ax.axis(): Atajos para el Control de Ejes

Forma conveniente de controlar varios aspectos de los ejes a la vez.

  • ax.axis('equal'): Escalas iguales en X e Y.
  • ax.axis('tight'): Ajusta límites a los datos.
  • ax.axis('off'): Oculta ejes.
  • ax.axis([xmin, xmax, ymin, ymax]): Establece límites.
Código 10.10.1 — Demostrando ax.axis()
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 4.5))

# Gráfico 1: Órbita elíptica
a = 5; b = 3 # Semiejes
t_orbita = np.linspace(0, 2*np.pi, 200)
x_orbita = a * np.cos(t_orbita); y_orbita = b * np.sin(t_orbita)
ax1.plot(x_orbita, y_orbita, color='navy', lw=2)
ax1.scatter(0,0, color='gold', s=200, marker='o', label='Estrella', edgecolor='black')
ax1.axis('equal') 
ax1.set_title("Órbita Elíptica con ax.axis('equal') 🪐", color='#7f1d1d')
ax1.legend()

# Gráfico 2: Función matemática con ejes 'off'
x_func = np.linspace(-3, 3, 100)
y_func = x_func**3 - 2*x_func
ax2.plot(x_func, y_func, color='darkgreen', lw=2.5)
ax2.axis('off') # Ocultar los ejes y el marco
ax2.set_title("Función Cúbica con ax.axis('off') 📈", color='#7f1d1d')

plt.tight_layout()
plt.show()

¡El Límite es tu Imaginación! Matplotlib ofrece muchísimas más opciones de personalización (anotaciones, flechas, formas, GridSpec, estilos plt.style.use(), etc.). Explora la galería oficial y la documentación. 🌌

11. Diagrama de Barras 📊

Los diagramas de barras son ideales para comparar magnitudes entre categorías o grupos.

Ejemplo Matemático: Notas por Materia

# Datos
materias = ['Álgebra', 'Cálculo', 'Física', 'Química']
notas = [85, 90, 78, 88]

# Crear figura
fig, ax = plt.subplots()

# Graficar
ax.bar(materias, notas, color='teal')

# Personalizar
ax.set_title('Promedio por Materia')
ax.set_ylabel('Nota')
ax.grid(True, axis='y', alpha=0.3)

plt.show()

Ejemplo Físico: Velocidad por Objeto

# Datos físicos
objetos = ['Coche', 'Moto', 'Bicicleta', 'Corredor']
velocidades = [120, 100, 30, 12]

# Graficar
fig, ax = plt.subplots()
ax.bar(objetos, velocidades, color='slateblue')

# Etiquetas y título
ax.set_title('Velocidad Máxima por Objeto')
ax.set_ylabel('Velocidad (km/h)')
ax.grid(True, axis='y', alpha=0.3)

plt.show()

12. Histogramas 📈

Los histogramas muestran cómo se distribuyen los valores de un conjunto de datos numéricos.

Ejemplo Matemático: Distribución de Calificaciones

# Generar datos aleatorios
import numpy as np
calificaciones = np.random.normal(loc=70, scale=10, size=200)

# Graficar
fig, ax = plt.subplots()
ax.hist(calificaciones, bins=15, color='mediumseagreen', edgecolor='black')

# Personalizar
ax.set_title('Distribución de Calificaciones')
ax.set_xlabel('Calificación')
ax.set_ylabel('Frecuencia')
ax.grid(True, axis='y', alpha=0.3)

plt.show()

13. Diagramas Circulares 🧁

Los gráficos de torta son útiles para mostrar proporciones relativas de una categoría respecto al total.

Ejemplo Matemático: Gastos Mensuales

# Datos
categorias = ['Alquiler', 'Comida', 'Transporte', 'Entretenimiento']
gastos = [1200, 400, 150, 100]

# Graficar
fig, ax = plt.subplots()
ax.pie(gastos, labels=categorias, autopct='%1.1f%%', startangle=90, colors=['#f97316', '#10b981', '#6366f1', '#ec4899'])

# Título
ax.set_title('Distribución de Gastos Mensuales')
plt.axis('equal')  # Hacer que sea circular

plt.show()

14. Gráficas 3D 📦

Con el módulo mplot3d, puedes graficar superficies, curvas espaciales y más.

Ejemplo Matemático: Superficie 3D

from mpl_toolkits.mplot3d import Axes3D

# Datos
x = np.linspace(-5, 5, 100)
y = np.linspace(-5, 5, 100)
X, Y = np.meshgrid(x, y)
Z = np.sin(np.sqrt(X**2 + Y**2))

# Graficar
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(X, Y, Z, cmap='viridis')

# Títulos
ax.set_title('Superficie 3D - Onda Senoidal')
ax.set_xlabel('Eje X')
ax.set_ylabel('Eje Y')
ax.set_zlabel('Eje Z')

plt.show()