Dlaczego wiele przykładów używa `fig, ax = plt.subplots ()` w Matplotlib / pyplot / python

265

Uczę się używać matplotlib, studiując przykłady, i wiele przykładów wydaje się zawierać linię podobną do następującej przed utworzeniem pojedynczego wątku ...

fig, ax = plt.subplots()

Oto kilka przykładów ...

Widzę, że ta funkcja jest często używana, mimo że w przykładzie próbuje się utworzyć tylko jeden wykres. Czy jest jakaś inna zaleta? Oficjalna wersja demonstracyjna subplots()służy również do f, ax = subplotstworzenia pojedynczego wykresu, a potem odwołuje się tylko do ax. To jest kod, którego używają.

# Just a figure and one subplot
f, ax = plt.subplots()
ax.plot(x, y)
ax.set_title('Simple plot')
neelshiv
źródło
11
cóż, jest krótki, zwięzły i w jednym kroku otrzymujesz referencję dwóch figur i osi. Jest pytoniczny, ponieważ jest piękny :)
cel

Odpowiedzi:

322

plt.subplots()to funkcja, która zwraca krotkę zawierającą figurę i obiekty osi. Dlatego podczas używania fig, ax = plt.subplots()rozpakuj tę krotkę do zmiennych figi ax. Posiadanie figjest przydatne, jeśli chcesz zmienić atrybuty na poziomie figury lub zapisać figurę jako plik obrazu później (np. Za pomocą fig.savefig('yourfilename.png')). Z pewnością nie musisz używać zwróconego obiektu figurowego, ale wiele osób korzysta z niego później, więc często można go zobaczyć. Ponadto wszystkie obiekty osi (obiekty, które mają metody drukowania), i tak mają obiekt figury nadrzędnej, a zatem:

fig, ax = plt.subplots()

jest bardziej zwięzłe niż to:

fig = plt.figure()
ax = fig.add_subplot(111)
jonchar
źródło
7
Bardzo dobre wytłumaczenie. Oto dokument na ten temat - matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.subplots
bretcj7
2
Dlaczego zawsze używamy 111 jako parametru w podplucie?
Priyansh
@Priyansh, ponieważ jest dziedziczony ze składni Matlaba
pcko1
@Priyansh Nie zawsze. Jeśli chcesz 4 wykresy, możesz to zrobić ax11, ax12, ax21, ax22za pomocą fig.add_subplot(221)(lub odpowiednio 222, 223, 224).
Guimoute
49

Tutaj tylko dodatek.

Pytanie brzmi: co zrobić, jeśli chcę więcej wykresów na rysunku?

Jak wspomniano w Doc, możemy użyć fig = plt.subplots(nrows=2, ncols=2)do ustawienia grupy podplotów z siatką (2,2) w obiekcie z jedną figurą.

Następnie, jak wiemy, fig, ax = plt.subplots()zwraca krotkę, spróbujmy fig, ax1, ax2, ax3, ax4 = plt.subplots(nrows=2, ncols=2)najpierw.

ValueError: not enough values to unpack (expected 4, got 2)

Zgłasza błąd, ale nie martw się, ponieważ teraz widzimy, że plt.subplots()faktycznie zwraca krotkę z dwoma elementami. Pierwszy musi być obiektem figurki, a drugi powinien być grupą obiektów podplotów.

Spróbujmy więc jeszcze raz:

fig, [[ax1, ax2], [ax3, ax4]] = plt.subplots(nrows=2, ncols=2)

i sprawdź typ:

type(fig) #<class 'matplotlib.figure.Figure'>
type(ax1) #<class 'matplotlib.axes._subplots.AxesSubplot'>

Oczywiście, jeśli użyjesz parametrów jako (nrows = 1, ncols = 4), wówczas format powinien mieć:

fig, [ax1, ax2, ax3, ax4] = plt.subplots(nrows=1, ncols=4)

Pamiętaj więc, aby zachować konstrukcję listy taką samą, jak siatkę podplotów, którą ustawiliśmy na rysunku.

Mam nadzieję, że byłoby to dla ciebie pomocne.

Duskash
źródło
2
nie zapomnij dodać plt.tight_layout (), jeśli twoje wątki mają tytuły
gota
12
Co jeśli masz dużo podplotów? Łatwiej to zrobić w ten sposób: fig, axes = plt.subplots(nrows=10, ncols=3)i axes = axes.flatten(). Teraz można odnieść do każdej poletko o indeksie: axes[0], axes[1]...
Guillaume
Co jeśli chcę, aby jedna z tych podplotów obejmowała wiele kolumn lub wierszy? czy można to zrobić za pomocą komendy subplots?
gota
1
@BallpointBen Nie jestem pewien, czy to działa, jeśli nrows=1, ponieważ wtedy axesjest zwracany płasko o długości równejncols
Ben
1
@BallpointBen Właśnie zdałem sobie sprawę, że możesz to naprawić, wykonując:fig, axes = plt.subplots(nrows=1, ncols=3, squeeze=False)
Ben
14

Jako uzupełnienie pytania i powyższych odpowiedzi istnieje również istotna różnica między plt.subplots()i plt.subplot(), zauważ brakujące 's'na końcu.

Można użyć, plt.subplots()aby utworzyć wszystkie ich wykresy podrzędne jednocześnie, a to zwraca liczbę i osie (liczba mnoga osi) wykresów podrzędnych jako krotkę. Postać można rozumieć jako płótno, na którym malujesz szkic.

# create a subplot with 2 rows and 1 columns
fig, ax = plt.subplots(2,1)

Natomiast możesz użyć, plt.subplot()jeśli chcesz dodać podploty osobno. Zwraca tylko oś jednego wykresu podrzędnego.

fig = plt.figure() # create the canvas for plotting
ax1 = plt.subplot(2,1,1) 
# (2,1,1) indicates total number of rows, columns, and figure number respectively
ax2 = plt.subplot(2,1,2)

Jest jednak plt.subplots()preferowany, ponieważ daje łatwiejsze opcje bezpośredniego dostosowania całej sylwetki

# for example, sharing x-axis, y-axis for all subplots can be specified at once
fig, ax = plt.subplots(2,2, sharex=True, sharey=True)

Wspólne osie podczas gdy za pomocą plt.subplot()trzeba będzie określić osobno dla każdej osi, co może stać się kłopotliwe.

Light_B
źródło
1
twoja linia kodu ax3 = plt.subplot(2,1,3) nie będzie działać, ponieważ jest 2 na 1, która ma tylko 2 wykresy.
Cloud Cho
1
dzięki, naprawiłem to. W ostatnim bloku kodu potrzebna była kolejna zmiana.
Light_B
2

Oprócz powyższych odpowiedzi można także sprawdzić typ obiektu, za pomocą type(plt.subplots())którego zwraca krotkę, z drugiej strony type(plt.subplot())zwraca, matplotlib.axes._subplots.AxesSubplotktórego nie można rozpakować.

John T.
źródło
4
Witamy w Stack Overflow! To jest naprawdę komentarz, a nie odpowiedź. Przy nieco większym przedstawicielu będziesz mógł dodawać komentarze . Dzięki!
Miroslav Glamuzina