Matplotlib: legenda globale e sottotrame a parte il titolo


125

Ho iniziato con matplot e ho gestito alcuni grafici di base, ma ora trovo difficile scoprire come fare alcune cose di cui ho bisogno ora :(

La mia vera domanda è come inserire un titolo globale e una leggenda globale su una figura con sottotrame.

Sto realizzando sottotrame 2x3 in cui ho molti grafici diversi in vari colori (circa 200). Per distinguerli (la maggior parte) ho scritto qualcosa di simile

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

(qualche idea su questo? :)) Ogni sottotrama ha la stessa funzione di stile.

Ora sto cercando di ottenere un titolo globale per tutte le sottotrame e anche una legenda globale che spieghi tutti gli stili. Inoltre devo rendere il carattere minuscolo per adattarsi a tutti i 200 stili lì (non ho bisogno di stili completamente unici, ma almeno qualche tentativo)

Qualcuno può aiutarmi a risolvere questo compito?


Risposte:


192

Titolo globale : nelle versioni più recenti di matplotlib è possibile utilizzare il metodo Figure.suptitle () di Figure:

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

In alternativa (in base al commento di @Steven C. Howell qui sotto (grazie!)), Usa la funzione matplotlib.pyplot.suptitle () :

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

64
Per coloro che importano in questo modo:, import matplotlib.pyplot as pltil comando potrebbe essere inserito semplicemente come plt.figure(); plt.suptitle('Title centered above all subplots'); plt.subplot(231); plt.plot(data[:,0], data[:,1]);ecc ...
Steven C. Howell

1
Grazie. Questa dovrebbe essere l'effettiva risposta selezionata.
gustafbstrom

62

Oltre alla risposta orbeckst, si potrebbe anche voler spostare le sottotrame verso il basso. Ecco un MWE in stile 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")

dà:

inserisci qui la descrizione dell'immagine


2
questa dovrebbe essere la risposta migliore
Statham

D'accordo! La risposta accettata introduce un'altra dipendenza, quindi non risponde adeguatamente alla domanda OP.
Yohan Obadia

7

Per le etichette della legenda è possibile utilizzare qualcosa come di seguito. Le etichette leggendarie sono le linee di trama salvate. modFreq sono dove il nome delle etichette effettive corrispondenti alle linee di trama. Quindi il terzo parametro è la posizione della legenda. Infine, puoi passare qualsiasi argomento come ho qui sotto, ma principalmente hai bisogno dei primi tre. Inoltre, dovresti farlo se imposti correttamente le etichette nel comando plot. Per chiamare solo la legenda con il parametro di posizione e trova le etichette in ciascuna delle righe. Ho avuto più fortuna nel creare la mia leggenda come di seguito. Sembra funzionare in tutti i casi in cui non è mai sembrato che il contrario procedesse correttamente. Se non capisci fammi sapere:

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)

È inoltre possibile utilizzare la gamba per modificare le dimensioni dei caratteri o quasi tutti i parametri della legenda.

Il titolo globale come indicato nel commento sopra può essere fatto aggiungendo del testo tramite il collegamento fornito: 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')

4

suptitlesembra la strada da percorrere, ma per quello che vale, figureha una transFigureproprietà che puoi usare:

fig=figure(1)
text(0.5, 0.95, 'test', transform=fig.transFigure, horizontalalignment='center')
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.