web-dev-qa-db-fra.com

Ajout d'une légende sous l'axe X pour un nuage de points à l'aide de matplotlib

Je suis assez nouveau pour python et pour la bibliothèque matplotlib. J'ai créé un nuage de points en utilisant matplotlib et je souhaite maintenant ajouter une légende un peu en dessous de l'axe des abscisses. Ceci est mon code: 

from matplotlib import pyplot as plt
import numpy as np
from pylab import *

file = open('distribution.txt', 'r')

txt="I need the caption to be present a little below X-axis"

x=[]
y=[]
for line in file:
    new=line.rstrip()
    mystring=new.split("\t")
    x.append(mystring[0])
    y.append(mystring[1])


fig = plt.figure()
ax1 = fig.add_axes((0.1,0.4,0.8,0.5))
ax1.set_title("This is my title")
ax1.set_xlabel('X-axis')
ax1.set_ylabel('Y-axis')
ax1.scatter(x,y, c='r')
fig.text(.05,.05,txt)
plt.xlim(0, 1.05)
plt.ylim(0, 2.5)
plt.show()

Comme vous pouvez le voir sur l'image, ma légende se situe bien en dessous du nuage de points, y a-t-il un moyen de la placer exactement sous l'axe des X? De plus, mon diagramme de dispersion a une apparence rectangulaire. Y a-t-il un moyen de le rendre carré?

 enter image description here

8
Mdhale

Quelque chose comme:

from matplotlib import pyplot as plt
import numpy as np

txt="I need the caption to be present a little below X-axis"

# make some synthetic data
x = np.linspace(0, 1, 512)
y = np.random.Rand(512)*2.3 + .1

fig = plt.figure()
ax1 = fig.add_axes((0.1, 0.2, 0.8, 0.7))

ax1.set_title("This is my title")
ax1.set_xlabel('X-axis')
ax1.set_ylabel('Y-axis')

# make the Edge colors match the facecolors
ax1.scatter(x,y, c='r', edgecolors='face')
# center text
fig.text(.5, .05, txt, ha='center')

# use OO interface    
ax1.set_xlim([0, 1.05])
ax1.set_ylim([0, 2.5])

# resize the figure to match the aspect ratio of the Axes    
fig.set_size_inches(7, 8, forward=True)

plt.show()

 example result

pourrait fonctionner. Rendre cela plus facile à faire est une priorité pour MPL en amont, mais nous cherchons toujours quelqu'un pour le faire. 

10
tacaswell

Vous pouvez simplement utiliser figtext. Vous pouvez également modifier la valeur des axes x et y comme vous le souhaitez. 

txt="I need the caption to be present a little below X-axis"
plt.figtext(0.5, 0.01, txt, wrap=True, horizontalalignment='center', fontsize=12)
11
Abu Shoeb

Premièrement, je me sens bizarre de poster une réponse contre le co-développeur principal de matplotlib. De toute évidence, @tacaswell connaît bien matplotlib bien mieux que jamais. Mais en même temps, sa réponse n'était pas assez dynamique pour moi. J'avais besoin d'une légende qui serait toujours basée sur la position de la variable xlabel et que je ne pouvais pas utiliser uniquement des annotations textuelles.

J'ai envisagé de changer simplement xlabel pour ajouter une nouvelle ligne et le texte de la légende, mais cela ne différencierait pas clairement la légende. Vous ne pouvez pas modifier la taille du texte ou le mettre en italique au milieu d'une chaîne de texte.

J'ai résolu ce problème en utilisant les capacités TeX de matplotlib. Voici ma solution:

from matplotlib import pyplot as plt
from matplotlib import rc
import numpy as np
from pylab import *

rc('text', usetex=True)

file = open('distribution.txt', 'r')

txt="I need the caption to be present a little below X-axis"

x=[]
y=[]
for line in file:
    new=line.rstrip()
    mystring=new.split("\t")
    x.append(mystring[0])
    y.append(mystring[1])


fig = plt.figure()
ax1 = fig.add_axes((0.1,0.4,0.8,0.5))
ax1.set_title("This is my title")
ax1.set_xlabel(r'\begin{center}X-axis\\*\textit{\small{' + txt + r'}}\end{center}')
ax1.set_ylabel('Y-axis')
ax1.scatter(x,y, c='r')
plt.xlim(0, 1.05)
plt.ylim(0, 2.5)
plt.show()

J'ai fait la même chose avec l'intrigue de dispersion aléatoire de la réponse de tacaswell, et voici mon résultat:

 Scatter plot with caption

Un avertissement: si vous ajustez cette option pour prendre les variables de chaîne d'entrée, il est possible que les chaînes ne soient pas correctement utilisées pour être utilisées avec TeX. L'échappement de code LaTeX est déjà couvert par Stack Overflow, à https://stackoverflow.com/a/25875504/1404311 . Je l'ai utilisé directement, et puis pourrait prendre des xlabels et des légendes arbitraires.

6
Scott Mermelstein

Une autre solution simple que j’ai utilisée lorsque je ne savais pas comment le faire d’une manière conçue ... si cela avait du sens, consistait simplement à ajouter de nouvelles lignes au xlabel plt.xlabel ("xaxis label\n\n\n\ncaption ") Ceci place simplement la légende quelques nouvelles lignes sous l’axe des x, ce qui la fait ressembler à une légende même si elle fait vraiment partie du label xaxis

2
Nicky V