Matplotlib - Légende mondiale et sous-parcelles de titre

125

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

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

Je fais des sous-graphiques 2x3 où j'ai beaucoup de graphiques différents dans différentes couleurs (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 pensées à ce sujet? :)) Chaque sous-intrigue a la même fonction de style.

J'essaye maintenant d'obtenir un titre global pour toutes les sous-parcelles et aussi une légende globale qui explique tous les styles. Je dois également rendre la police minuscule pour qu'elle s'adapte aux 200 styles (je n'ai pas besoin de styles complètement uniques, mais au moins une tentative)

Quelqu'un peut-il m'aider à résoudre cette tâche?

Gerenuk
la source

Réponses:

192

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

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

Alternativement (basé sur le commentaire de @Steven C. Howell ci-dessous (merci!)), Utilisez la fonction matplotlib.pyplot.suptitle () :

 import matplotlib.pyplot as plt
 # plot stuff
 # ...
 plt.suptitle("Title centered above all subplots", fontsize=14)
Orbeckst
la source
64
Pour ceux qui importent comme ceci:, import matplotlib.pyplot as pltla commande pourrait être saisie simplement comme plt.figure(); plt.suptitle('Title centered above all subplots'); plt.subplot(231); plt.plot(data[:,0], data[:,1]);etc ...
Steven C. Howell
1
Merci. Cela devrait être la réponse sélectionnée.
gustafbstrom
62

En plus de la réponse orbeckst, on peut également vouloir décaler les sous- graphiques vers le bas. Voici un MWE de style POO:

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:

entrez la description de l'image ici

Adobe
la source
2
cela devrait être la meilleure réponse
Statham
D'accord ! La réponse acceptée introduit une autre dépendance et ne répond donc pas correctement à la question OP.
Yohan Obadia
7

Pour les étiquettes de légende, vous pouvez utiliser quelque chose comme ci-dessous. Les légendes sont les lignes de tracé enregistrées. modFreq est l'endroit où le nom des étiquettes réelles correspondant aux lignes de tracé. Ensuite, le troisième paramètre est l'emplacement de la légende. Enfin, vous pouvez transmettre tous les arguments car je suis ici mais j'ai principalement besoin des trois premiers. De plus, vous êtes censé le faire si vous définissez correctement les étiquettes dans la commande plot. Pour appeler simplement la légende avec le paramètre d'emplacement et il trouve les étiquettes dans chacune des lignes. J'ai eu plus de chance de créer ma propre légende comme ci-dessous. Semble fonctionner dans tous les cas où il n'a jamais semblé que l'inverse se déroule 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 les tailles de police ou presque n'importe quel paramètre de la légende.

Le titre global comme indiqué dans le commentaire ci-dessus peut être fait en ajoutant du texte via 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')
J Spen
la source
4

suptitlesemble la voie à suivre, mais pour ce que ça vaut, le figurea une transFigurepropriété que vous pouvez utiliser:

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