Agregar una leyenda a PyPlot en Matplotlib de la manera más simple posible

263

TL; DR -> ¿Cómo se puede crear una leyenda para un gráfico de líneas en Matplotlib's PyPlotsin crear ninguna variable adicional?

Considere la secuencia de comandos gráfica a continuación:

if __name__ == '__main__':
    PyPlot.plot(total_lengths, sort_times_bubble, 'b-',
                total_lengths, sort_times_ins, 'r-',
                total_lengths, sort_times_merge_r, 'g+',
                total_lengths, sort_times_merge_i, 'p-', )
    PyPlot.title("Combined Statistics")
    PyPlot.xlabel("Length of list (number)")
    PyPlot.ylabel("Time taken (seconds)")
    PyPlot.show()

Como puede ver, este es un uso muy básico de matplotlib's PyPlot. Idealmente, esto genera un gráfico como el siguiente:

Grafico

Nada especial, lo sé. Sin embargo, no está claro qué datos se están trazando dónde (estoy tratando de trazar los datos de algunos algoritmos de clasificación, la longitud en función del tiempo empleado, y me gustaría asegurarme de que la gente sepa qué línea es cuál). Por lo tanto, necesito una leyenda, sin embargo, echando un vistazo al siguiente ejemplo a continuación ( del sitio oficial ):

ax = subplot(1,1,1)
p1, = ax.plot([1,2,3], label="line 1")
p2, = ax.plot([3,2,1], label="line 2")
p3, = ax.plot([2,3,1], label="line 3")

handles, labels = ax.get_legend_handles_labels()

# reverse the order
ax.legend(handles[::-1], labels[::-1])

# or sort them by labels
import operator
hl = sorted(zip(handles, labels),
            key=operator.itemgetter(1))
handles2, labels2 = zip(*hl)

ax.legend(handles2, labels2)

Verás que necesito crear una variable adicional ax. ¿Cómo puedo agregar una leyenda a mi gráfico sin tener que crear esta variable adicional y mantener la simplicidad de mi script actual?

Juegos Brainiac
fuente
Estoy confundido por su preocupación de crear una variable adicional. Tienes que hacer esos objetos detrás de escena de todos modos.
tacaswell 01 de
1
@tcaswell Bueno, déjame intentar calmarlos. No quiero crear variables adicionales, porque agrega complejidad a todo el script. Estoy tratando de enseñar esto a un grupo de estudiantes, y como no lo han usado matplotlibantes, quería mantener las cosas lo más simples posible. Además, si echa un vistazo a la respuesta de Rob, es mucho más simple que el ejemplo que se muestra en el sitio web. Espero que eso ayude.
Juegos Brainiac
1
Yo diría que el uso de la interfaz de la máquina de estado hace que sea más difícil de entender a largo plazo porque gran parte de esto se hace "por arte de magia". Además, la convención es usar en import matplotlib.pyplot as pltlugar dePyPlot
tacaswell

Respuestas:

441

Agregue un label=a cada una de sus plot()llamadas y luego llame legend(loc='upper left').

Considere esta muestra (probada con Python 3.8.0):

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 20, 1000)
y1 = np.sin(x)
y2 = np.cos(x)

plt.plot(x, y1, "-b", label="sine")
plt.plot(x, y2, "-r", label="cosine")
plt.legend(loc="upper left")
plt.ylim(-1.5, 2.0)
plt.show()

ingrese la descripción de la imagen aquí Ligeramente modificado de este tutorial: http://jakevdp.github.io/mpl_tutorial/tutorial_pages/tut1.html

Robᵩ
fuente
2
¿Hay alguna manera de hacer esto si no conoce las etiquetas en el momento en que se traza la serie? ¿Es una forma de agregar etiquetas a una serie después de que ya se ha trazado? ¿O tal vez una forma de modificar las etiquetas de marcador de posición antes de mostrar la leyenda?
davidA
13
plt.legend(loc='upper left')también funciona, de donde pltes import matplotlib.pyplot as plt.
Matt Kleinsmith
Gracias, @eric, por notar esto. He actualizado el código.
Robᵩ
Upvoted debido a desbordamiento de pila es impresionante y buenas respuestas puede cambiar
Eric
1
@davidA Sí, simplemente puede pasar una lista de cadenas a plt.legend:plt.legend(['First Label', 'Second Label'])
Apollys apoya a Monica el
36

Puede acceder a la instancia de Axes ( ax) con plt.gca(). En este caso, puedes usar

plt.gca().legend()

Puede hacerlo utilizando la label=palabra clave en cada una de sus plt.plot()llamadas o asignando sus etiquetas como una tupla o lista dentro legend, como en este ejemplo de trabajo:

import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-0.75,1,100)
y0 = np.exp(2 + 3*x - 7*x**3)
y1 = 7-4*np.sin(4*x)
plt.plot(x,y0,x,y1)
plt.gca().legend(('y0','y1'))
plt.show()

pltGcaLegend

Sin embargo, si necesita acceder a la instancia de Axes más de una vez, le recomiendo guardarlo en la variable axcon

ax = plt.gca()

y luego llamando en axlugar de plt.gca().

cameronroytaylor
fuente
¡Copie y pegue la respuesta que no requiere lectura y con una imagen! esta respuesta merece más crédito
Gulzar
14

Aquí hay un ejemplo para ayudarte ...

fig = plt.figure(figsize=(10,5))
ax = fig.add_subplot(111)
ax.set_title('ADR vs Rating (CS:GO)')
ax.scatter(x=data[:,0],y=data[:,1],label='Data')
plt.plot(data[:,0], m*data[:,0] + b,color='red',label='Our Fitting 
Line')
ax.set_xlabel('ADR')
ax.set_ylabel('Rating')
ax.legend(loc='best')
plt.show()

ingrese la descripción de la imagen aquí

Akash Kandpal
fuente
2
Tengo curiosidad, ¿por qué su línea de ajuste está tan lejos de los datos?
Apollys apoya a Monica el
13

Una trama simple para las curvas seno y coseno con una leyenda.

Usado matplotlib.pyplot

import math
import matplotlib.pyplot as plt
x=[]
for i in range(-314,314):
    x.append(i/100)
ysin=[math.sin(i) for i in x]
ycos=[math.cos(i) for i in x]
plt.plot(x,ysin,label='sin(x)')  #specify label for the corresponding curve
plt.plot(x,ycos,label='cos(x)')
plt.xticks([-3.14,-1.57,0,1.57,3.14],['-$\pi$','-$\pi$/2',0,'$\pi$/2','$\pi$'])
plt.legend()
plt.show()

Tramas de pecado y coseno (haga clic para ver la imagen)

sajalagrawal
fuente
6

Agregue etiquetas a cada argumento en su llamada a la trama correspondiente a la serie que está graficando, es decir label = "series 1"

Luego, simplemente agregue Pyplot.legend()al final de su secuencia de comandos y la leyenda mostrará estas etiquetas.

blaklaybul
fuente
Esta es la idea correcta, pero nunca añadir las etiquetas para la leyenda estará vacía
tacaswell
4

Puede agregar una documentación de leyenda personalizada

first = [1, 2, 4, 5, 4]
second = [3, 4, 2, 2, 3]
plt.plot(first,'g--', second, 'r--')
plt.legend(['First List','Second List'], loc='upper left')
plt.show()

ingrese la descripción de la imagen aquí

Boris Yakubchik
fuente
0
    # Dependencies
    import numpy as np
    import matplotlib.pyplot as plt

    #Set Axes
    # Set x axis to numerical value for month
    x_axis_data = np.arange(1,13,1)
    x_axis_data

    # Average weather temp
    points = [39, 42, 51, 62, 72, 82, 86, 84, 77, 65, 55, 44]

    # Plot the line
    plt.plot(x_axis_data, points)
    plt.show()

    # Convert to Celsius C = (F-32) * 0.56
    points_C = [round((x-32) * 0.56,2) for x in points]
    points_C

    # Plot using Celsius
    plt.plot(x_axis_data, points_C)
    plt.show()

    # Plot both on the same chart
    plt.plot(x_axis_data, points)
    plt.plot(x_axis_data, points_C)

    #Line colors
    plt.plot(x_axis_data, points, "-b", label="F")
    plt.plot(x_axis_data, points_C, "-r", label="C")

    #locate legend
    plt.legend(loc="upper left")
    plt.show()
James Turner
fuente