Buscar..


Leyenda simple

Suponga que tiene varias líneas en la misma trama, cada una de un color diferente, y desea hacer una leyenda para decir qué representa cada línea. Puede hacer esto pasando una etiqueta a cada una de las líneas cuando llame a plot() , por ejemplo, la siguiente línea se etiquetará como "Mi línea 1" .

ax.plot(x, y1, color="red", label="My Line 1")

Esto especifica el texto que aparecerá en la leyenda para esa línea. Ahora para hacer visible la leyenda real, podemos llamar ax.legend()

Por defecto, creará una leyenda dentro de un cuadro en la esquina superior derecha de la parcela. Puede pasar argumentos a legend() para personalizarlo. Por ejemplo, podemos colocarlo en la esquina inferior derecha, sin un cuadro de marco que lo rodea, y crear un título para la leyenda llamando a lo siguiente:

ax.legend(loc="lower right", title="Legend Title", frameon=False)

A continuación se muestra un ejemplo:

Imagen de ejemplo de leyenda simple

import matplotlib.pyplot as plt

# The data
x =  [1, 2, 3]
y1 = [2,  15, 27]
y2 = [10, 40, 45]
y3 = [5,  25, 40]

# Initialize the figure and axes
fig, ax = plt.subplots(1, figsize=(8, 6))

# Set the title for the figure
fig.suptitle('Simple Legend Example ', fontsize=15)

# Draw all the lines in the same plot, assigning a label for each one to be
# shown in the legend
ax.plot(x, y1, color="red", label="My Line 1")
ax.plot(x, y2, color="green", label="My Line 2")
ax.plot(x, y3, color="blue", label="My Line 3")

# Add a legend with title, position it on the lower right (loc) with no box framing (frameon)
ax.legend(loc="lower right", title="Legend Title", frameon=False)

# Show the plot
plt.show()

Leyenda colocada fuera de la trama

A veces es necesario o deseable colocar la leyenda fuera de la trama. El siguiente código muestra cómo hacerlo.

Imagen de la trama con leyenda fuera de la trama

import matplotlib.pylab as plt
fig, ax = plt.subplots(1, 1, figsize=(10,6)) # make the figure with the size 10 x 6 inches
fig.suptitle('Example of a Legend Being Placed Outside of Plot')

# The data
x =  [1, 2, 3]
y1 = [1, 2, 4]
y2 = [2, 4, 8]
y3 = [3, 5, 14]

# Labels to use for each line
line_labels = ["Item A", "Item B", "Item C"]

# Create the lines, assigning different colors for each one.
# Also store the created line objects
l1 = ax.plot(x, y1, color="red")[0]
l2 = ax.plot(x, y2, color="green")[0]
l3 = ax.plot(x, y3, color="blue")[0]

fig.legend([l1, l2, l3],              # List of the line objects
           labels= line_labels,       # The labels for each line
           loc="center right",        # Position of the legend
           borderaxespad=0.1,         # Add little spacing around the legend box
           title="Legend Title")      # Title for the legend

# Adjust the scaling factor to fit your legend text completely outside the plot
# (smaller value results in more space being made for the legend)
plt.subplots_adjust(right=0.85)

plt.show()

Otra forma de colocar la leyenda fuera de la trama es usar bbox_to_anchor + bbox_extra_artists + bbox_inches='tight' , como se muestra en el siguiente ejemplo:

introduzca la descripción de la imagen aquí

import matplotlib.pyplot as plt

# Data 
all_x = [10,20,30]
all_y = [[1,3], [1.5,2.9],[3,2]]

# Plot
fig = plt.figure(1)
ax = fig.add_subplot(111)
ax.plot(all_x, all_y)

# Add legend, title and axis labels
lgd = ax.legend([ 'Lag ' + str(lag) for lag in all_x], loc='center right', bbox_to_anchor=(1.3, 0.5))
ax.set_title('Title')
ax.set_xlabel('x label')
ax.set_ylabel('y label')    

fig.savefig('image_output.png',
            dpi=300, 
            format='png', 
            bbox_extra_artists=(lgd,),
            bbox_inches='tight')

Leyenda única compartida en múltiples subparcelas

A veces tendrá una cuadrícula de subparcelas y desea tener una sola leyenda que describa todas las líneas para cada una de las subparcelas como se muestra en la siguiente imagen.

Imagen de leyenda única a través de múltiples subparcelas

Para hacer esto, deberá crear una leyenda global para la figura en lugar de crear una leyenda en el nivel de los ejes (lo que creará una leyenda independiente para cada subparcela). Esto se logra llamando a fig.legend() como se puede ver en el código para el siguiente código.

fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(10,4))
fig.suptitle('Example of a Single Legend Shared Across Multiple Subplots')

# The data
x =  [1, 2, 3]
y1 = [1, 2, 3]
y2 = [3, 1, 3]
y3 = [1, 3, 1]
y4 = [2, 2, 3]

# Labels to use in the legend for each line
line_labels = ["Line A", "Line B", "Line C", "Line D"]

# Create the sub-plots, assigning a different color for each line.
# Also store the line objects created
l1 = ax1.plot(x, y1, color="red")[0]
l2 = ax2.plot(x, y2, color="green")[0]
l3 = ax3.plot(x, y3, color="blue")[0]
l4 = ax3.plot(x, y4, color="orange")[0] # A second line in the third subplot

# Create the legend
fig.legend([l1, l2, l3, l4],     # The line objects
           labels=line_labels,   # The labels for each line
           loc="center right",   # Position of legend
           borderaxespad=0.1,    # Small spacing around legend box
           title="Legend Title"  # Title for the legend
           )

# Adjust the scaling factor to fit your legend text completely outside the plot
# (smaller value results in more space being made for the legend)
plt.subplots_adjust(right=0.85)

plt.show()

Algo a tener en cuenta sobre el ejemplo anterior es lo siguiente:

l1 = ax1.plot(x, y1, color="red")[0]

Cuando se llama a plot() , devuelve una lista de objetos line2D . En este caso, solo devuelve una lista con un solo objeto line2D , que se extrae con la indexación [0] y se almacena en l1 .

Una lista de todos los objetos de line2D que nos interesa incluir en la leyenda debe pasarse como primer argumento a fig.legend() . El segundo argumento de fig.legend() también es necesario. Se supone que es una lista de cadenas para usar como etiquetas para cada línea en la leyenda.

Los otros argumentos pasados ​​a fig.legend() son puramente opcionales, y solo ayudan a afinar la estética de la leyenda.

Múltiples leyendas en los mismos ejes

Si llama a plt.legend() o ax.legend() más de una vez, se eliminará la primera leyenda y se dibujará una nueva. Según la documentación oficial :

Esto se ha hecho para que sea posible llamar a legend () repetidamente para actualizar la leyenda a los últimos manejadores de los ejes.

Sin embargo, no se preocupe: todavía es bastante simple agregar una segunda leyenda (o la tercera, o la cuarta ...) a los ejes. En el ejemplo aquí, trazamos dos líneas, luego trazamos marcadores en sus máximos y mínimos respectivos. Una leyenda es para las líneas y la otra para los marcadores.

import matplotlib.pyplot as plt
import numpy as np

# Generate data for plotting:  
x = np.linspace(0,2*np.pi,100)
y0 = np.sin(x)
y1 = .9*np.sin(.9*x)
# Find their maxima and minima and store
maxes = np.empty((2,2))
mins = np.empty((2,2))
for k,y in enumerate([y0,y1]):
    maxloc = y.argmax()
    maxes[k] = x[maxloc], y[maxloc]
    minloc = y.argmin()
    mins[k] = x[minloc], y[minloc]

# Instantiate figure and plot
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(x,y0, label='y0')
ax.plot(x,y1, label='y1')
# Plot maxima and minima, and keep references to the lines
maxline, = ax.plot(maxes[:,0], maxes[:,1], 'r^')
minline, = ax.plot(mins[:,0], mins[:,1], 'ko')

# Add first legend:  only labeled data is included
leg1 = ax.legend(loc='lower left')
# Add second legend for the maxes and mins.
# leg1 will be removed from figure
leg2 = ax.legend([maxline,minline],['max','min'], loc='upper right')
# Manually add the first legend back
ax.add_artist(leg1)

introduzca la descripción de la imagen aquí

La clave es asegurarse de que tiene referencias a los objetos de leyenda. El primero que leg1 ( leg1 ) se elimina de la figura cuando agregas el segundo, pero el objeto leg1 todavía existe y se puede volver a ax.add_artist con ax.add_artist .

Lo realmente genial es que aún puedes manipular ambas leyendas. Por ejemplo, agregue lo siguiente al final del código anterior:

leg1.get_lines()[0].set_lw(8)
leg2.get_texts()[1].set_color('b')

introduzca la descripción de la imagen aquí

Finalmente, vale la pena mencionar que en el ejemplo solo las líneas recibieron etiquetas cuando se trazaron, lo que significa que ax.legend() agrega solo esas líneas al leg1 . La leyenda para los marcadores ( leg2 ), por lo tanto, requería las líneas y etiquetas como argumentos cuando se leg2 instancias. Podríamos, alternativamente, haber dado etiquetas a los marcadores cuando se trazaron también. Pero entonces ambas llamadas a ax.legend habrían requerido algunos argumentos adicionales para que cada leyenda contuviera solo los elementos que queríamos.



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow