¿Cuál es la diferencia entre dibujar gráficos usando gráficos, ejes o figuras en matplotlib?

101

Estoy un poco confundido sobre lo que sucede en el backend cuando dibujo gráficos en matplotlib, tbh, no tengo claro la jerarquía de la trama, los ejes y la figura. Leí la documentación y fue útil, pero todavía estoy confundido ...

El siguiente código dibuja la misma trama de tres formas diferentes:

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

Ahora mi pregunta es:

  1. ¿Cuál es la diferencia entre los tres? Quiero decir, ¿qué pasa debajo del capó cuando se llama a cualquiera de los 3 métodos?

  2. ¿Qué método debe usarse cuando y cuáles son los pros y los contras de usar alguno en esos?

hashcode55
fuente
8
Ya leí eso, pero no encontré la respuesta satisfactoria en absoluto. Explica la jerarquía, pero también suscita la confusión ¿por qué no existe una forma convencional, por qué el objeto figura incluso se expone?
hashcode55
No estoy seguro si refirió esta documentación exacta matplotlib.org/users/artists.html . Esto responde a su pregunta de por qué se expone la figura. Personalmente, esta es la mejor explicación de matplotlib que he encontrado. El objeto Figura le permite agregar sus propios Artistas directamente sin ejes, aunque rara vez se usa a menos que desee modificar el "parche" de la figura en sí, etc. Tenga en cuenta que la figura es el contenedor principal y aloja ejes y artistas.
Sandeep

Respuestas:

55

Método 1

plt.plot(x, y)

Esto le permite trazar solo una figura con coordenadas (x, y). Si solo desea obtener un gráfico, puede usarlo de esta manera.

Método 2

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

Esto le permite trazar una o varias figuras en la misma ventana. Mientras lo escribe, trazará solo una figura, pero puede hacer algo como esto:

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

Trazará 4 figuras que se denominan ax1, ax2, ax3 y ax4 cada una, pero en la misma ventana. Esta ventana se dividirá en 4 partes con mi ejemplo.

Método 3

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

No lo usé, pero puedes encontrar documentación.

Ejemplo:

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

ingrese la descripción de la imagen aquí ingrese la descripción de la imagen aquí

Otro ejemplo:

ingrese la descripción de la imagen aquí

Essex
fuente
@ hashcode55 cada figura es independiente. Les mostraré un ejemplo
Essex
1
@ hashcode55 Editaré con un ejemplo (solo la figura de mis investigaciones en Astrofísica, el script es demasiado largo (1300 líneas));) Cada figura es independiente;)
Essex
3
Sé que esto es quisquilloso, pero lo hago porque el matplotliblenguaje me resulta confuso, y esta pregunta aparece cuando se busca "ejes frente a figura en matplotlib". Para otros novatos, esta pregunta ayudó a responder eso. Creo que la redacción aquí podría ser más clara que subplots()devolverá Axesobjetos en una sola figure.
Hendy
34

Los nombres de los objetos

Matplotlib está fuertemente orientado a objetos y sus objetos principales son la figura y los ejes (encuentro el nombreaxes un poco engañoso, pero probablemente sea solo yo).

Puede pensar en la figura como un lienzo , del cual normalmente especifica las dimensiones y posiblemente, por ejemplo, el color de fondo, etc. figura , esencialmente de dos maneras, colocando otros objetos en él (principalmente ejes , pero también etiquetas de texto, etc.) y guardar su contenido con savefig.

Se puede pensar en un eje como una especie de navaja suiza, un objeto práctico que ofrece una herramienta (por ejemplo .plot, .scatter,.hist etc) para todo, en su mayoría. Puede colocar uno, dos, ... muchos ejes dentro de una figura usando uno de los muchos métodos diferentes.

La pltinterfaz

La interfaz de procedimiento plt se desarrolló originalmente para imitar la interfaz MATLAB ™, pero no es realmente diferente de la interfaz orientada a objetos, incluso si no hace una referencia directa a los objetos principales (es decir, una figura y un eje ), estos objetos son instancia automáticamente y cada método plt se traduce, esencialmente, a una llamada de uno de los métodos de los objetos fundamentales subyacentes: por ejemplo, a plt.plot()es unhidden_axes.plot a plt.savefiges a hidden_figure.savefig.

En todo momento puedes controlar estos objetos ocultos usando plt.gcfyplt.gca , y esto a veces es necesario cuando uno de los métodos de objeto no se ha portado a un método en el espacio de nombres plt .

Me gustaría agregar que el espacio de nombres plt contiene también una serie de métodos convenientes para instanciar, de diferentes maneras, la figura y ejes .

Tus ejemplos

1er camino

plt.plot(x, y)

Aquí solo usa la interfaz plt , solo puede usar un solo eje en cada figura , pero esto es lo que quiere cuando está haciendo una exploración de sus datos, una receta rápida que hace el trabajo ...

2do camino

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

Aquí utiliza un método de conveniencia en el espacio de nombres plt para dar un nombre (y un identificador) a su objeto de ejes , pero por cierto también hay una figura oculta . Luego puede usar el objeto axes para trazar, hacer un histograma, etc., todo lo que puede hacer con la interfaz plt , pero también puede acceder a todos sus atributos y modificarlos con mayor libertad.

3er camino

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

Aquí comienza a crear instancias de una figura usando un método de conveniencia en el espacio de nombres plt y luego usa solo la interfaz orientada a objetos.

Es posible omitir el método de conveniencia plt ( matplotlib.figure.Figure) pero luego debe ajustar la figura para una mejor experiencia interactiva (después de todo, es un método de conveniencia ).

Recomendaciones personales

Sugiero desnudo plt.plot, plt.scatteren el contexto de una sesión interactiva, posiblemente usando IPython con su %matplotlibcomando mágico, y también en el contexto de un cuaderno exploratorio de Jupyter.

Por otro lado, el enfoque orientado a objetos, más algunos plt métodos de conveniencia, es el camino a seguir.

  • si tiene un problema permanente que resolver de una vez por todas con una disposición personalizada de subtramas finamente ajustadas,
  • si desea incrustar Matplotlib en la interfaz de usuario de un programa que escriba.

Hay una gran área gris entre estos extremos y si me preguntas qué hacer, simplemente diría "Depende" ...

gboffi
fuente
2
"Encuentro el nombre axes un poco engañoso, pero probablemente sea solo yo" - no, soy yo también. Aunque no se puede cambiar.
Laryx Decidua
1
Otra cosa que no puedo entender es por qué la gente usa el fig, ax = plt.subplot()idioma cuando no quiere subtramas. En tales casos encontré más fácil el estilo "procedimental". "Pero probablemente sea solo yo ..." :-)
Laryx Decidua
@LaryxDecidua Puedo ver de inmediato dos buenas razones ① "Explícito es mejor que implícito" ② desea utilizar los métodos de Figure o Axes que no están disponibles en la API de procedimiento, pero posiblemente hay otros…
gboffi
Sí, me suscribo por completo a 1). Re 2): la mayoría de las veces la API de procedimiento es suficiente. Al final del día, creo que se reduce a las preferencias personales, algo sobre lo que uno no debería discutir :-)
Laryx Decidua