Matplotlib Legend: Guía completa para agregar y personalizar leyendas
Updated on
Un gráfico sin leyenda obliga a los lectores a adivinar qué línea es cuál. Emparejan colores mentalmente, leen mal los datos y sacan conclusiones incorrectas. Agregar una leyenda con plt.legend() es simple -- pero controlar dónde aparece, cómo se ve y evitar que cubra tus datos requiere más trabajo del que la mayoría de los tutoriales muestran.
Esta guía cubre todo, desde la creación básica de leyendas hasta la personalización avanzada: colocación dentro y fuera del gráfico, diseños multicolumna, handles personalizados y leyendas para figuras complejas.
Leyenda básica
Etiquetas automáticas
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
plt.plot(x, np.sin(x), label='sin(x)')
plt.plot(x, np.cos(x), label='cos(x)')
plt.legend()
plt.show()El parámetro label en plot() define lo que aparece en la leyenda. Llama a plt.legend() para mostrarla.
Estilo orientado a objetos
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
fig, ax = plt.subplots(figsize=(8, 5))
ax.plot(x, np.sin(x), label='sin(x)')
ax.plot(x, np.cos(x), label='cos(x)')
ax.legend()
plt.show()Colocación de la leyenda
Usando el parámetro loc
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
fig, ax = plt.subplots(figsize=(8, 5))
ax.plot(x, np.sin(x), label='sin(x)')
ax.plot(x, np.cos(x), label='cos(x)')
# Ubicaciones comunes
ax.legend(loc='upper right') # Predeterminado
# ax.legend(loc='upper left')
# ax.legend(loc='lower right')
# ax.legend(loc='lower left')
# ax.legend(loc='center')
# ax.legend(loc='best') # Selecciona automáticamente el lugar con menos superposición
plt.show()Todas las opciones de loc
| Cadena loc | Número loc |
|---|---|
'best' | 0 |
'upper right' | 1 |
'upper left' | 2 |
'lower left' | 3 |
'lower right' | 4 |
'right' | 5 |
'center left' | 6 |
'center right' | 7 |
'lower center' | 8 |
'upper center' | 9 |
'center' | 10 |
Posicionamiento preciso con bbox_to_anchor
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
fig, ax = plt.subplots(figsize=(8, 5))
ax.plot(x, np.sin(x), label='sin(x)')
ax.plot(x, np.cos(x), label='cos(x)')
ax.plot(x, np.sin(x) + np.cos(x), label='sin(x) + cos(x)')
# Posicionar leyenda en coordenadas específicas (x, y) en fracción de ejes
ax.legend(loc='upper left', bbox_to_anchor=(0.02, 0.98))
plt.show()Leyenda fuera del gráfico
Cuando la leyenda superpone datos, muévela fuera:
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
fig, ax = plt.subplots(figsize=(10, 5))
for i in range(6):
ax.plot(x, np.sin(x + i * 0.5), label=f'Phase {i}')
# Colocar leyenda a la derecha del gráfico
ax.legend(loc='center left', bbox_to_anchor=(1.0, 0.5))
plt.tight_layout()
plt.show()import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
fig, ax = plt.subplots(figsize=(8, 6))
for i in range(5):
ax.plot(x, np.sin(x + i), label=f'Series {i+1}')
# Colocar leyenda debajo del gráfico
ax.legend(loc='upper center', bbox_to_anchor=(0.5, -0.1), ncol=5)
plt.tight_layout()
plt.show()Estilo de la leyenda
Tamaño de fuente y marco
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
fig, ax = plt.subplots(figsize=(8, 5))
ax.plot(x, np.sin(x), label='sin(x)')
ax.plot(x, np.cos(x), label='cos(x)')
ax.legend(
fontsize=12,
frameon=True, # Mostrar borde (predeterminado True)
framealpha=0.8, # Transparencia del borde
facecolor='lightyellow', # Color de fondo
edgecolor='gray', # Color del borde
shadow=True, # Sombra
)
plt.show()Diseño multicolumna
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
fig, ax = plt.subplots(figsize=(10, 5))
for i in range(8):
ax.plot(x, np.sin(x + i * 0.4), label=f'Signal {i+1}')
# 4 columnas para leyenda compacta
ax.legend(ncol=4, loc='upper center', fontsize=9)
plt.show()Título de la leyenda
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
fig, ax = plt.subplots(figsize=(8, 5))
ax.plot(x, x**2, label='Quadratic')
ax.plot(x, x**1.5, label='Power 1.5')
ax.plot(x, x, label='Linear')
ax.legend(title='Modelos de crecimiento', title_fontsize=13, fontsize=11)
plt.show()Handles personalizados de leyenda
Entradas manuales de leyenda
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
import matplotlib.lines as mlines
import numpy as np
fig, ax = plt.subplots(figsize=(8, 5))
# Plotear sin etiquetas
ax.scatter(np.random.randn(50), np.random.randn(50), c='blue', s=20)
ax.scatter(np.random.randn(50) + 2, np.random.randn(50), c='red', s=20)
# Crear handles personalizados
blue_patch = mpatches.Patch(color='blue', label='Grupo A')
red_patch = mpatches.Patch(color='red', label='Grupo B')
line_handle = mlines.Line2D([], [], color='green', linestyle='--', label='Umbral')
ax.legend(handles=[blue_patch, red_patch, line_handle])
plt.show()Leyenda para diagrama de dispersión con mapeo de colores
import matplotlib.pyplot as plt
import numpy as np
fig, ax = plt.subplots(figsize=(8, 5))
categories = ['A', 'B', 'C']
colors = ['#e74c3c', '#3498db', '#2ecc71']
for cat, color in zip(categories, colors):
x = np.random.randn(30)
y = np.random.randn(30)
ax.scatter(x, y, c=color, label=f'Categoría {cat}', alpha=0.7, s=50)
ax.legend()
plt.show()Opciones de personalización de leyenda
| Parámetro | Descripción | Ejemplo |
|---|---|---|
loc | Cadena o número de posición | 'upper right', 2 |
bbox_to_anchor | Punto de anclaje (x, y) | (1.0, 0.5) |
ncol | Número de columnas | 3 |
fontsize | Tamaño del texto | 12, 'small' |
title | Título de la leyenda | 'My Legend' |
frameon | Mostrar marco | True, False |
framealpha | Transparencia del marco | 0.8 |
facecolor | Color de fondo | 'white' |
edgecolor | Color del borde | 'gray' |
shadow | Sombra | True |
markerscale | Multiplicador de tamaño de marcador | 1.5 |
labelspacing | Espacio vertical entre entradas | 0.5 |
handlelength | Longitud de la línea de leyenda | 2.0 |
Ejemplos prácticos
Leyenda para múltiples tipos de gráficos
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(5)
values = [23, 45, 56, 78, 32]
trend = [20, 35, 50, 65, 40]
fig, ax = plt.subplots(figsize=(8, 5))
ax.bar(x, values, alpha=0.7, label='Real', color='steelblue')
ax.plot(x, trend, 'ro-', label='Tendencia', linewidth=2)
ax.axhline(y=50, color='green', linestyle='--', label='Objetivo')
ax.legend(loc='upper left')
ax.set_xlabel('Trimestre')
ax.set_ylabel('Ingresos ($K)')
plt.show()Leyendas separadas para ejes dobles
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(2020, 2027)
revenue = [100, 120, 115, 140, 160, 175, 200]
employees = [50, 55, 52, 60, 70, 75, 85]
fig, ax1 = plt.subplots(figsize=(8, 5))
line1 = ax1.plot(x, revenue, 'b-o', label='Ingresos ($M)')
ax1.set_ylabel('Ingresos ($M)', color='blue')
ax2 = ax1.twinx()
line2 = ax2.plot(x, employees, 'r-s', label='Empleados')
ax2.set_ylabel('Empleados', color='red')
# Combinar leyendas
lines = line1 + line2
labels = [l.get_label() for l in lines]
ax1.legend(lines, labels, loc='upper left')
plt.show()Exploración interactiva de datos
Al iterar sobre la estética del gráfico y la colocación de la leyenda, PyGWalker (opens in a new tab) te permite construir visualizaciones interactivas en Jupyter arrastrando columnas -- leyendas, colores y tamaños se generan automáticamente:
import pandas as pd
import pygwalker as pyg
df = pd.read_csv('your_data.csv')
walker = pyg.walk(df)Preguntas frecuentes
¿Cómo agrego una leyenda a un gráfico de Matplotlib?
Agrega label='name' a cada llamada de plot(), scatter() o bar(), luego llama a plt.legend() o ax.legend(). La leyenda usa automáticamente las etiquetas que proporcionaste.
¿Cómo muevo la leyenda fuera del gráfico?
Usa bbox_to_anchor con loc. Para el lado derecho: ax.legend(loc='center left', bbox_to_anchor=(1.0, 0.5)). Para abajo: ax.legend(loc='upper center', bbox_to_anchor=(0.5, -0.1)). Llama a plt.tight_layout() para evitar recortes.
¿Cómo cambio el tamaño de fuente de la leyenda en Matplotlib?
Pasa fontsize a legend(): ax.legend(fontsize=14) o usa tamaños de cadena como 'small', 'medium', 'large'. Para el título: ax.legend(title='Title', title_fontsize=16).
¿Cómo creo una leyenda con múltiples columnas?
Usa el parámetro ncol: ax.legend(ncol=3) crea un diseño de 3 columnas. Esto es útil cuando tienes muchas entradas de leyenda y quieres un diseño horizontal compacto.
¿Cómo elimino el borde de la leyenda?
Establece frameon=False: ax.legend(frameon=False). Para mantener el marco pero hacerlo transparente, usa framealpha=0: ax.legend(framealpha=0).
Conclusión
Las leyendas de Matplotlib comienzan con parámetros label y plt.legend(). Usa loc para posiciones estándar, bbox_to_anchor para mover la leyenda fuera del gráfico, ncol para diseños multicolumna y parámetros de estilo como fontsize, frameon y shadow para personalización. Para gráficos con muchas series, coloca la leyenda fuera del área de ejes y llama a tight_layout() para evitar recortes. Para figuras complejas con ejes dobles, combina los handles de línea manualmente para crear una leyenda unificada.