Jaka jest różnica między rysowaniem wykresów za pomocą wykresu, osi lub figury w matplotlib?

107

Jestem trochę zdezorientowany, co dzieje się na zapleczu, kiedy rysuję wykresy w matplotlib, tbh, nie jestem jasny z hierarchią działek, osi i figur. Przeczytałem dokumentację i była pomocna, ale nadal jestem zdezorientowany ...

Poniższy kod rysuje ten sam wykres na trzy różne sposoby -

#creating the arrays for testing
x = np.arange(1, 100)
y = np.sqrt(x)
#1st way
plt.plot(x, y)
#2nd way
ax = plt.subplot()
ax.plot(x, y)
#3rd way
figure = plt.figure()
new_plot = figure.add_subplot(111)
new_plot.plot(x, y)

Teraz moje pytanie brzmi -

  1. Jaka jest różnica między wszystkimi trzema, mam na myśli to, co dzieje się pod maską, gdy wywoływana jest jedna z 3 metod?

  2. Której metody należy użyć, kiedy i jakie są wady i zalety jej używania?

hashcode55
źródło
8
Już to przeczytałem, ale odpowiedź nie była dla mnie satysfakcjonująca. Wyjaśnia hierarchię, ale też budzi zamieszanie, dlaczego nie ma konwencjonalnego sposobu, dlaczego figura jest nawet wyeksponowana?
hashcode55
Nie jestem pewien, czy odesłałeś dokładnie tę dokumentację matplotlib.org/users/artists.html . To odpowiada na pytanie, dlaczego figura jest w ogóle odsłonięta. Osobiście jest to najlepsze wyjaśnienie działania matplotlib, jakie znalazłem. Obiekt Figure umożliwia dodawanie własnych Artystów bezpośrednio bez osi, chociaż jest to rzadko używane, chyba że chcesz zmodyfikować „łatkę” samej figury itp. Zauważ, że figura jest kontenerem nadrzędnym i zawiera osie i artystów.
Sandeep

Odpowiedzi:

58

Metoda 1

plt.plot(x, y)

Pozwala to narysować tylko jedną figurę ze współrzędnymi (x, y). Jeśli chcesz uzyskać tylko jedną grafikę, możesz użyć tego sposobu.

Metoda 2

ax = plt.subplot()
ax.plot(x, y)

Pozwala to na wykreślenie jednej lub kilku figur w tym samym oknie. W trakcie pisania narysujesz tylko jedną figurę, ale możesz zrobić coś takiego:

fig1, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2)

Narysujesz 4 figury, które są nazwane ax1, ax2, ax3 i ax4, każda ale w tym samym oknie. To okno zostanie podzielone na 4 części z moim przykładem.

Metoda 3

fig = plt.figure()
new_plot = fig.add_subplot(111)
new_plot.plot(x, y)

Nie korzystałem z tego, ale możesz znaleźć dokumentację.

Przykład:

import numpy as np
import matplotlib.pyplot as plt

# Method 1 #

x = np.random.rand(10)
y = np.random.rand(10)

figure1 = plt.plot(x,y)

# Method 2 #

x1 = np.random.rand(10)
x2 = np.random.rand(10)
x3 = np.random.rand(10)
x4 = np.random.rand(10)
y1 = np.random.rand(10)
y2 = np.random.rand(10)
y3 = np.random.rand(10)
y4 = np.random.rand(10)

figure2, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2)
ax1.plot(x1,y1)
ax2.plot(x2,y2)
ax3.plot(x3,y3)
ax4.plot(x4,y4)

plt.show()

wprowadź opis obrazu tutaj wprowadź opis obrazu tutaj

Inny przykład:

wprowadź opis obrazu tutaj

Essex
źródło
@ hashcode55 każda cyfra jest niezależna. Pokażę wam przykład
Essex
1
@ hashcode55 edytuję z przykładem (tylko liczba z moich badań w Astrofizyce, skrypt jest za długi (1300 wierszy));) Każda liczba jest niezależna;)
Essex
3
Wiem, że jest to trudne, ale robię to, ponieważ matplotlibjęzyk był dla mnie zagmatwany, a to pytanie pojawia się podczas wyszukiwania informacji „osie kontra figura w matplotlib”. W przypadku innych noobów to pytanie pomogło odpowiedzieć na to pytanie. Myślę, że sformułowanie tutaj mogłoby być bardziej jasne, że subplots()zwróci Axesobiekty na singlu figure.
Hendy
40

Nazwy obiektów

Matplotlib jest silnie zorientowany obiektowo, a jego głównymi obiektami są figura i osie (nazwa axesjest trochę myląca, ale prawdopodobnie to tylko ja).

Możesz myśleć o figurze jak o płótnie , którego zazwyczaj określasz wymiary i ewentualnie np. Kolor tła itp. Używasz płótna, figury , zasadniczo na dwa sposoby, umieszczając na niej inne obiekty (głównie osie , ale także etykiety tekstowe itp.) i zapisując jego zawartość z savefig.

Można myśleć o osiach jako pewnego rodzaju szwajcarski scyzoryk, poręczny obiekt, który oferuje narzędzie (np .plot, .scatter, .histetc) do wszystkiego, głównie. Możesz umieścić jedną, dwie, ... wiele osi wewnątrz figury, używając jednej z wielu różnych metod.

pltinterfejs

PLT interfejs proceduralny został pierwotnie opracowany do naśladowania ™ interfejs MATLAB, ale nie jest tak naprawdę różni się od interfejsu obiektowego, nawet jeśli nie robią bezpośrednie odniesienie do głównych obiektów (tj figura i an osie ) obiekty te są tworzone automatycznie i każda metoda plt jest zasadniczo tłumaczona na wywołanie jednej z metod podstawowych obiektów podstawowych: np. a plt.plot()jest a hidden_axes.ploti a plt.savefigjest a hidden_figure.savefig.

W każdej chwili możesz mieć uchwyt na te ukryte obiekty za pomocą plt.gcfi plt.gca, co czasami jest konieczne, gdy jedna z metod obiektu nie została przeniesiona do metody w przestrzeni nazw plt .

Chciałbym dodać, że przestrzeń nazw plt zawiera również szereg wygodnych metod tworzenia instancji, na różne sposoby, figury i osi .

Twoje przykłady

1 sposób

plt.plot(x, y)

Tutaj używasz tylko interfejsu plt , możesz użyć tylko jednej osi na każdej figurze , ale właśnie tego chcesz, gdy eksplorujesz swoje dane, szybki przepis, który wykonuje pracę ...

2 sposób

ax = plt.subplot()
ax.plot(x, y)

Tutaj używasz wygodnej metody w przestrzeni nazw plt, aby nadać nazwę (i uchwyt) swojemu obiektowi axes , ale przy okazji jest też ukryta figura . Możesz później użyć obiektu axes do kreślenia, tworzenia histogramu itp. Wszystkich rzeczy, które możesz zrobić z interfejsem plt , ale możesz także uzyskać dostęp do wszystkich jego atrybutów i modyfikować je z większą swobodą.

3 sposób

figure = plt.figure()
new_plot = figure.add_subplot(111)
new_plot.plot(x, y)

Tutaj zaczynasz tworzenie instancji figury przy użyciu wygodnej metody w przestrzeni nazw plt, a później używasz tylko interfejsu obiektowego.

Możliwe jest ominięcie wygodnej metody plt ( matplotlib.figure.Figure), ale musisz wtedy dostosować liczbę, aby uzyskać lepsze wrażenia z interakcji (w końcu jest to wygodna metoda).

Osobiste rekomendacje

Proponuję gołe plt.plot, plt.scatterw kontekście sesji interaktywnej, możliwie użycie IPythona z jego %matplotlibmagicznym poleceniem, a także w kontekście eksploracyjnego notatnika Jupyter.

Z drugiej strony podejście obiektowe plus kilka plt wygodnych metod to droga do zrobienia

  • jeśli masz stały problem do rozwiązania raz na zawsze dzięki dostosowanemu układowi precyzyjnie dostrojonych wątków pobocznych,
  • jeśli chcesz osadzić Matplotlib w interfejsie użytkownika programu, który piszesz.

Między tymi skrajnościami jest duża szara strefa i jeśli zapytasz mnie, co mam zrobić, powiedziałbym po prostu „To zależy” ...

gboffi
źródło
2
„Osie nazw uważam za nieco mylące, ale prawdopodobnie to tylko ja” - nie, to też ja. Nie można go jednak zmienić.
Laryx Decidua
1
Kolejna rzecz, której po prostu nie mogę zrozumieć, dlaczego ludzie używają fig, ax = plt.subplot()idiomu, kiedy nie chcą wątków cząstkowych. W takich przypadkach łatwiej mi było zastosować styl „proceduralny”. "Ale prawdopodobnie to tylko ja ..." :-)
Laryx Decidua
@LaryxDecidua Od razu widzę dwa dobre powody ① „Wyraźne jest lepsze niż niejawne” want chcesz użyć metod Figure lub Axes, które nie są dostępne w proceduralnym API - ale prawdopodobnie są inne…
gboffi
Tak, w pełni subskrybuję 1). Do 2): w większości przypadków wystarczy API proceduralne. Na koniec dnia myślę, że sprowadza się to do osobistych preferencji - o czym nie należy się kłócić :-)
Laryx Decidua