Ajouter une légende à PyPlot dans Matplotlib de la manière la plus simple possible

263

TL; DR -> Comment peut - on créer une légende pour un graphique de ligne dans Matplotlib« s PyPlotsans créer des variables supplémentaires?

Veuillez considérer le script graphique ci-dessous:

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()

Comme vous pouvez le voir, c'est une utilisation très basique de matplotlib« s PyPlot. Cela génère idéalement un graphique comme celui ci-dessous:

Graphique

Rien de spécial, je sais. Cependant, il n'est pas clair quelles données sont tracées où (j'essaie de tracer les données de certains algorithmes de tri, la durée en fonction du temps, et je voudrais m'assurer que les gens savent quelle ligne est laquelle). Ainsi, j'ai besoin d'une légende, cependant, jetant un œil à l'exemple suivant ci-dessous ( sur le site officiel ):

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)

Vous verrez que j'ai besoin de créer une variable supplémentaire ax. Comment puis-je ajouter une légende à mon graphique sans avoir à créer cette variable supplémentaire et à conserver la simplicité de mon script actuel?

Games Brainiac
la source
Je suis confus par votre souci de créer une variable supplémentaire. Vous devez de toute façon faire ces objets dans les coulisses.
tacaswell
1
@tcaswell Eh bien, laissez-moi essayer de les apaiser. Je ne veux pas créer de variables supplémentaires, car cela ajoute de la complexité à l'ensemble du script. J'essaie d' enseigner cela à un groupe d'étudiants, et comme ils ne l'ont pas utilisé matplotlibauparavant, je voulais que les choses soient aussi simples que possible. De plus, si vous jetez un coup d'œil à la réponse de Rob, c'est beaucoup plus simple que l'exemple montré sur le site Web. J'espère que ça aide.
Jeux Brainiac
1
Je dirais que l'utilisation de l'interface de la machine à états la rend plus difficile à comprendre à long terme, car une grande partie se fait «par magie». En outre, la convention est d'utiliser import matplotlib.pyplot as pltau lieu dePyPlot
tacaswell

Réponses:

442

Ajoutez un label=à chacun de vos plot()appels, puis appelez legend(loc='upper left').

Considérez cet exemple (testé avec 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()

entrez la description de l'image ici Légèrement modifié à partir de ce tutoriel: http://jakevdp.github.io/mpl_tutorial/tutorial_pages/tut1.html

Robᵩ
la source
2
Y a-t-il un moyen de le faire si vous ne connaissez pas les étiquettes au moment où la série est tracée? C'est-à-dire un moyen d'ajouter des étiquettes à une série après qu'elle a déjà été tracée? Ou peut-être un moyen de modifier les étiquettes d'espace réservé avant d'afficher la légende?
davidA
13
plt.legend(loc='upper left')fonctionne également, d'où pltvient import matplotlib.pyplot as plt.
Matt Kleinsmith
Merci, @eric, de l'avoir noté. J'ai mis à jour le code.
Robᵩ
Surévalué car le débordement de pile est génial et les bonnes réponses peuvent changer
Eric
1
@davidA Oui, vous pouvez simplement passer une liste de chaînes dans plt.legend:plt.legend(['First Label', 'Second Label'])
Apollys prend en charge Monica
36

Vous pouvez accéder à l'instance Axes ( ax) avec plt.gca(). Dans ce cas, vous pouvez utiliser

plt.gca().legend()

Vous pouvez le faire en utilisant le label=mot - clé dans chacun de vos plt.plot()appels ou en attribuant vos étiquettes en tant que tuple ou liste à l'intérieur legend, comme dans cet exemple de travail:

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

Cependant, si vous devez accéder à l'instance Axes plusieurs fois, je vous recommande de l'enregistrer dans la variable axavec

ax = plt.gca()

puis appeler axau lieu de plt.gca().

cameronroytaylor
la source
réponse copier-coller qui ne nécessite aucune lecture, et avec une photo! cette réponse mérite plus de crédit
Gulzar
14

Voici un exemple pour vous aider ...

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()

entrez la description de l'image ici

Akash Kandpal
la source
2
Je suis juste curieux, pourquoi votre ligne d'ajustement est-elle si éloignée des données?
Apollys prend en charge Monica
13

Un tracé simple pour les courbes sinus et cosinus avec une légende.

Utilisé 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()

Parcelles Sin et Cosine (cliquez pour voir l'image)

sajalagrawal
la source
6

Ajoutez des étiquettes à chaque argument de votre appel de tracé correspondant à la série qu'il représente, c'est-à-dire label = "series 1"

Ensuite, ajoutez simplement Pyplot.legend()au bas de votre script et la légende affichera ces étiquettes.

blaklaybul
la source
C'est la bonne idée, mais vous n'ajoutez jamais les étiquettes, la légende sera donc vide
tacaswell
4

Vous pouvez ajouter une documentation de légende personnalisée

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()

entrez la description de l'image ici

Boris Yakubchik
la source
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
la source