Matplotlib - globalna legenda i wątki poboczne

125

Zacząłem od matplot i zarządzałem kilkoma podstawowymi wątkami, ale teraz trudno mi dowiedzieć się, jak zrobić coś, czego teraz potrzebuję :(

Moje aktualne pytanie brzmi, jak umieścić tytuł globalny i globalną legendę na figurze z wątkami pobocznymi.

Robię podploty 2x3, gdzie mam wiele różnych wykresów w różnych kolorach (około 200). Aby rozróżnić (większość) z nich napisałem coś w stylu

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

(masz jakieś przemyślenia na ten temat? :)) Każdy wątek cząstkowy ma tę samą funkcję stylu.

Teraz staram się uzyskać globalny tytuł dla wszystkich wątków pobocznych, a także globalną legendę, która wyjaśnia wszystkie style. Muszę również zmniejszyć czcionkę, aby pasowała do wszystkich 200 stylów (nie potrzebuję całkowicie unikalnych stylów, ale przynajmniej próbuję)

Czy ktoś może mi pomóc rozwiązać to zadanie?

Gerenuk
źródło

Odpowiedzi:

192

Tytuł globalny : W nowszych wersjach matplotlib można użyć metody Figure.suptitle ()Figure :

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

Alternatywnie (na podstawie poniższego komentarza @Stevena C. Howella (dziękuję!)) Użyj funkcji matplotlib.pyplot.suptitle () :

 import matplotlib.pyplot as plt
 # plot stuff
 # ...
 plt.suptitle("Title centered above all subplots", fontsize=14)
orbeckst
źródło
64
Dla tych, którzy importują w ten import matplotlib.pyplot as pltsposób:, polecenie można wprowadzić po prostu jako plt.figure(); plt.suptitle('Title centered above all subplots'); plt.subplot(231); plt.plot(data[:,0], data[:,1]);itp ...
Steven C. Howell
1
Dzięki. To powinna być faktycznie wybrana odpowiedź.
gustafbstrom
62

Oprócz najobszerniejszej odpowiedzi można również chcieć przesunąć wykresy cząstkowe w dół. Oto MWE w stylu 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")

daje:

wprowadź opis obrazu tutaj

Cegła suszona na słońcu
źródło
2
to powinna być najlepsza odpowiedź
Statham
Zgoda! Przyjęta odpowiedź wprowadza kolejną zależność, stąd nie odpowiada poprawnie na pytanie PO.
Yohan Obadia
7

W przypadku etykiet legendy można użyć czegoś takiego jak poniżej. Etykiety legendy to zapisane linie działki. modFreq to nazwa rzeczywistych etykiet odpowiadających liniom wykresu. Następnie trzecim parametrem jest lokalizacja legendy. Na koniec możesz przekazać dowolne argumenty, które tutaj przedstawiłem, ale potrzebujesz głównie pierwszych trzech. Powinieneś także, jeśli poprawnie ustawisz etykiety w poleceniu kreślenia. Wystarczy wywołać legendę z parametrem lokalizacji i znajduje etykiety w każdym z wierszy. Miałem większe szczęście, że stworzyłem własną legendę, jak poniżej. Wydaje się działać we wszystkich przypadkach, w których nigdy nie wydawało się, że odwrotna droga działa prawidłowo. Jeśli nie rozumiesz, daj mi znać:

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)

Możesz także użyć nogi, aby zmienić rozmiar czcionki lub prawie dowolny parametr legendy.

Tytuł globalny, jak podano w powyższym komentarzu, można zrobić, dodając tekst za pomocą podanego linku: 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
źródło
4

suptitlewydaje się być drogą do zrobienia, ale warto, figurema transFigurewłaściwość, z której możesz korzystać:

fig=figure(1)
text(0.5, 0.95, 'test', transform=fig.transFigure, horizontalalignment='center')
matematyka
źródło