165 votes

Matplotlib - légende globale et titre à côté des sous-graphes

J'ai commencé avec matplot et j'ai réussi quelques tracés de base, mais maintenant j'ai du mal à découvrir comment faire certaines choses dont j'ai besoin maintenant :(

Ma question est de savoir comment placer un titre global et une légende globale sur une figure avec des sous-parties.

Je fais des sous-graphes 2x3 où j'ai beaucoup de graphiques différents dans des couleurs variées (environ 200). Pour distinguer (la plupart) d'entre eux, j'ai écrit quelque chose comme

def style(i, total):
    return dict(color=jet(i/total),
                linestyle=["-", "--", "-.", ":"][i%4],
                marker=["+", "*", "1", "2", "3", "4", "s"][i%7])

fig=plt.figure()
p0=fig.add_subplot(321)
for i, y in enumerate(data):
    p0.plot(x, trans0(y), "-", label=i, **style(i, total))
# and more subplots with other transN functions

(des idées à ce sujet ? :)) Chaque intrigue secondaire a la même fonction de style.

J'essaie maintenant d'obtenir un titre global pour toutes les sous-parties ainsi qu'une légende globale qui explique tous les styles. J'ai également besoin de rendre la police minuscule pour y faire tenir les 200 styles (je n'ai pas besoin de styles complètement uniques, mais au moins quelques tentatives).

Quelqu'un peut-il m'aider à résoudre ce problème ?

268voto

orbeckst Points 448

Titre global : Dans les versions plus récentes de matplotlib, on peut utiliser Figure.suptitle() méthode de Figure :

import matplotlib.pyplot as plt
fig = plt.gcf()
fig.suptitle("Title centered above all subplots", fontsize=14)

Alternativement (sur la base de @Steven C. Howell ci-dessous (merci !)), utilisez la fonction matplotlib.pyplot.suptitle() fonction :

 import matplotlib.pyplot as plt
 # plot stuff
 # ...
 plt.suptitle("Title centered above all subplots", fontsize=14)

88voto

Adobe Points 1592

En plus de la orbeckst répondre on pourrait aussi vouloir déplacer les intrigues secondaires vers le bas. Voici un MWE dans le style OOP :

import matplotlib.pyplot as plt

fig = plt.figure()
st = fig.suptitle("suptitle", fontsize="x-large")

ax1 = fig.add_subplot(311)
ax1.plot([1,2,3])
ax1.set_title("ax1")

ax2 = fig.add_subplot(312)
ax2.plot([1,2,3])
ax2.set_title("ax2")

ax3 = fig.add_subplot(313)
ax3.plot([1,2,3])
ax3.set_title("ax3")

fig.tight_layout()

# shift subplots down:
st.set_y(0.95)
fig.subplots_adjust(top=0.85)

fig.savefig("test.png")

donne :

enter image description here

7voto

J Spen Points 819

Pour les étiquettes de légende, on peut utiliser quelque chose comme ce qui suit. Legendlabels sont les lignes de tracé sauvegardées. modFreq sont les noms des étiquettes correspondant aux lignes de tracé. Le troisième paramètre est l'emplacement de la légende. Enfin, vous pouvez passer n'importe quel argument comme je l'ai fait ici, mais vous avez surtout besoin des trois premiers. De plus, vous êtes censé définir les étiquettes correctement dans la commande plot. Il suffit d'appeler legend avec le paramètre location pour qu'il trouve les étiquettes dans chacune des lignes. J'ai eu plus de chance en créant ma propre légende comme ci-dessous. Cela semble fonctionner dans tous les cas, alors que je n'ai jamais réussi à faire fonctionner l'autre méthode correctement. Si vous ne comprenez pas, faites-le moi savoir :

legendLabels = []
for i in range(modSize):
    legendLabels.append(ax.plot(x,hstack((array([0]),actSum[j,semi,i,semi])), color=plotColor[i%8], dashes=dashes[i%4])[0]) #linestyle=dashs[i%4]       
legArgs = dict(title='AM Templates (Hz)',bbox_to_anchor=[.4,1.05],borderpad=0.1,labelspacing=0,handlelength=1.8,handletextpad=0.05,frameon=False,ncol=4, columnspacing=0.02) #ncol,numpoints,columnspacing,title,bbox_transform,prop
leg = ax.legend(tuple(legendLabels),tuple(modFreq),'upper center',**legArgs)
leg.get_title().set_fontsize(tick_size)

Vous pouvez également utiliser la jambe pour modifier la taille des polices ou presque n'importe quel paramètre de la légende.

Le titre global tel que mentionné dans le commentaire ci-dessus peut être réalisé en ajoutant du texte selon le lien fourni : http://matplotlib.sourceforge.net/examples/pylab_examples/newscalarformatter_demo.html

f.text(0.5,0.975,'The new formatter, default settings',horizontalalignment='center',
       verticalalignment='top')

4voto

mathtick Points 963

suptitle semble être la meilleure solution, mais pour ce qu'elle vaut, la figure a une transFigure que vous pouvez utiliser :

fig=figure(1)
text(0.5, 0.95, 'test', transform=fig.transFigure, horizontalalignment='center')

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X