Qual è la differenza tra disegnare grafici utilizzando grafico, assi o figura in matplotlib?


101

Sono un po 'confuso cosa succede al backend quando disegno grafici in matplotlib, tbh, non sono chiaro con la gerarchia di trama, assi e figura. Ho letto la documentazione ed è stato utile ma sono ancora confuso ...

Il codice seguente disegna la stessa trama in tre modi diversi:

#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)

Ora la mia domanda è:

  1. Qual è la differenza tra tutti e tre, voglio dire cosa succede sotto il cofano quando viene chiamato uno dei 3 metodi?

  2. Quale metodo dovrebbe essere utilizzato quando e quali sono i pro ei contro dell'uso di qualsiasi metodo?


8
L'ho già letto ma non ho trovato la risposta per niente soddisfacente. Spiega la gerarchia, ma solleva anche la confusione perché non c'è un modo convenzionale, perché l'oggetto figura è addirittura esposto?
hashcode55

Non sono sicuro che tu abbia fatto riferimento a questa esatta documentazione matplotlib.org/users/artists.html . Questo risponde alla tua domanda sul perché la figura sia persino esposta. Personalmente questa è la migliore spiegazione di matplotlib che ho trovato. L'oggetto Figura ti consente di aggiungere i tuoi artisti direttamente senza assi sebbene questo sia usato raramente a meno che tu non voglia modificare la "patch" della figura stessa, ecc. Nota che la figura è il contenitore genitore e ospita assi e artisti.
Sandeep

Risposte:


55

Metodo 1

plt.plot(x, y)

Ciò consente di tracciare solo una figura con coordinate (x, y). Se vuoi solo ottenere un'immagine, puoi usarla in questo modo.

Metodo 2

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

Ciò consente di tracciare una o più figure nella stessa finestra. Mentre lo scrivi, traccerai solo una figura, ma puoi creare qualcosa del genere:

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

Tracciamo 4 figure chiamate ax1, ax2, ax3 e ax4 ciascuna ma sulla stessa finestra. Questa finestra sarà solo divisa in 4 parti con il mio esempio.

Metodo 3

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

Non l'ho usato, ma puoi trovare la documentazione.

Esempio:

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()

inserisci qui la descrizione dell'immagine inserisci qui la descrizione dell'immagine

Altro esempio:

inserisci qui la descrizione dell'immagine


@ hashcode55 ogni cifra è indipendente. Ti mostrerò un esempio
Essex,

1
@ hashcode55 Modificherò con un esempio (solo la cifra delle mie ricerche in Astrofisica, lo script è troppo lungo (1300 righe));) Ogni cifra è indipendente;)
Essex

3
So che questo è pignolo, ma lo sto facendo perché il matplotliblinguaggio mi confondeva, e questa domanda si presenta quando cerco "assi vs. figura in matplotlib". Per altri niubbi, questa domanda ha aiutato a rispondere. Penso che la formulazione qui potrebbe essere più chiara che subplots()restituirà Axesoggetti su un singolo figure.
Hendy

34

I nomi degli oggetti

Matplotlib è fortemente orientato agli oggetti ei suoi oggetti principali sono la figura e gli assi (trovo il nome axesun po 'fuorviante, ma probabilmente sono solo io).

Puoi pensare alla figura come a una tela , di cui in genere specifichi le dimensioni e possibilmente ad es. Il colore di sfondo ecc. Ecc. Usi la tela, la figura , essenzialmente in due modi, posizionando altri oggetti su di essa (principalmente assi , ma anche etichette di testo ecc.) e salvarne il contenuto con savefig.

Si può pensare a un asse come una sorta di coltellino svizzero, un oggetto pratico che offre uno strumento (ad esempio .plot, .scatter, .histecc) per tutto, per lo più. Puoi posizionare uno, due, ... molti assi all'interno di una figura usando uno dei tanti metodi differenti.

L' pltinterfaccia

L' interfaccia procedurale plt è stata originariamente sviluppata per imitare l'interfaccia MATLAB ™ ma non è molto diversa dall'interfaccia orientata agli oggetti, anche se non si fa un riferimento diretto agli oggetti principali (cioè una figura e un asse ) questi oggetti sono istanziata automaticamente e ogni metodo plt viene, essenzialmente, tradotto in una chiamata di uno dei metodi degli oggetti fondamentali sottostanti: ad esempio, a plt.plot()è a hidden_axes.plote a plt.savefigè a hidden_figure.savefig.

In ogni momento puoi avere un handle su questi oggetti nascosti usando plt.gcfe plt.gca, e questo a volte è necessario quando uno dei metodi dell'oggetto non è stato portato su un metodo nello spazio dei nomi plt .

Vorrei aggiungere che lo spazio dei nomi plt contiene anche una serie di metodi convenienti per istanziare, in modi diversi, figure e assi .

I tuoi esempi

1 ° modo

plt.plot(x, y)

Qui usi solo l' interfaccia plt , puoi usare solo un singolo asse in ogni figura , ma questo è quello che vuoi quando stai facendo un'esplorazione dei tuoi dati, una ricetta veloce che porta a termine il lavoro ...

2 ° modo

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

Qui usi un metodo comodo nello spazio dei nomi plt per dare un nome (e una maniglia) al tuo oggetto assi , ma a proposito c'è anche una figura nascosta . Successivamente è possibile utilizzare l' oggetto assi per tracciare, creare un istogramma, ecc., Tutto ciò che è possibile fare con l' interfaccia plt , ma è anche possibile accedere a tutti i suoi attributi e modificarli con maggiore libertà.

Terza via

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

Qui inizi a creare un'istanza di una figura usando un comodo metodo nello spazio dei nomi plt e in seguito utilizzi solo l'interfaccia orientata agli oggetti.

È possibile bypassare il metodo di convenienza plt ( matplotlib.figure.Figure) ma è necessario modificare la figura per una migliore esperienza interattiva (dopo tutto, è un metodo conveniente ).

Raccomandazioni personali

Suggerisco di nudo plt.plot, plt.scatternel contesto di una sessione interattiva, possibilmente utilizzando IPython con il suo %matplotlibcomando magico, e anche nel contesto di un notebook Jupyter esplorativo.

D'altra parte l'approccio orientato agli oggetti, più alcuni plt metodi convenienti, è la strada da percorrere

  • se hai un problema permanente da risolvere una volta per tutte con una disposizione personalizzata di sottotrame finemente sintonizzate,
  • se vuoi incorporare Matplotlib nell'interfaccia utente di un programma che scrivi.

C'è una vasta area grigia tra questi estremi e se mi chiedi cosa fare ti direi semplicemente "Dipende" ...


2
"Trovo il nome assi un po 'fuorviante, ma probabilmente sono solo io" - no, sono anche io. Non può essere cambiato però.
Laryx Decidua

1
Un'altra cosa che non riesco a capire perché le persone usano l' fig, ax = plt.subplot()idioma quando non vogliono sottotrame. In questi casi ho trovato più semplice lo stile "procedurale". "Ma probabilmente sono solo io ..." :-)
Laryx Decidua

@LaryxDecidua Vedo subito due buone ragioni ① "Esplicito è meglio di implicito" ② vuoi usare i metodi di Figure o Axes che non sono disponibili nell'API procedurale - ma forse ce ne sono altri ...
gboffi

Sì, mi iscrivo completamente a 1). Ri 2): il più delle volte è sufficiente l'API procedurale. Alla fine della giornata penso che si riduca alle preferenze personali - qualcosa su cui non si dovrebbe discutere :-)
Laryx Decidua
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.