Saltar al contenido

Manual de introducción a matplotlib.pyplot (II): Creando y manejando ventanas y configurando la sesión

Este artículo se actualizó el 2020/04/18 para usar las últimas versiones de las bibliotecas que se comentan.

Esto pretende ser un tutorial del módulo pyplot de la librería matplotlib. El tutorial lo dividiremos de la siguiente forma (que podrá ir cambiando a medida que vayamos avanzando).

  1. Primeros pasos
  2. Creando ventanas, manejando ventanas y configurando la sesión
  3. Configuración del gráfico
  4. Tipos de gráfico I
  5. Tipos de gráfico II
  6. Tipos de gráfico III
  7. Tipos de gráfico IV
  8. Texto y anotaciones (arrow, annotate, table, text…)
  9. Herramientas estadísticas (acorr, cohere, csd, psd, specgram, spy, xcorr, …)
  10. Eventos e interactividad (connect, disconnect, ginput, waitforbuttonpress…)
  11. Miscelánea

[Para este tutorial se ha usado python 3.7.6, ipython 7.13.0, numpy 1.17.2 y matplotlib 3.1.1]

[DISCLAIMER: Muchos de los gráficos que vamos a representar no tienen ningún sentido físico y los resultados solo pretenden mostrar el uso de la librería].
En todo momento supondremos que se ha iniciado la sesión y se ha hecho:

Como ya comentamos anteriormente, el módulo pyplot de matplotlib se suele usar para hacer pruebas rápidas desde la línea de comandos, programitas cortos o programas donde los gráficos serán, en general, sencillos.

Normalmente, cuando iniciamos la sesión, esta no está puesta en modo interactivo. En modo interactivo, cada vez que metemos código nuevo relacionado con el gráfico o la ventana (recordad, una instancia de matplotlib.axes.Axes o de matplotlib.figure.Figure, respectivamente), este se actualizará. Cuando no estamos en modo interactivo, el gráfico no se actualiza hasta que llamemos a show() (si no hay una ventana abierta) o draw() (normalmente no lo usaréis para nada) explícitamente. Veamos como es esto:

Si acabamos de iniciar sesión deberíamos estar en modo no interactivo. Para comprobarlo hacemos lo siguiente:

Y nos devolverá:

Si el resultado es False significa que estamos en modo no interactivo. Esto significa que si hacemos lo siguiente:

No lanzará una ventana hasta que lo pidamos explícitamente mediante:

Podemos conmutar a modo interactivo o no usando plt.ion() y plt.ioff(), que lo que hacen es poner el modo interactivo en ‘on’ o en ‘off’, respectivamente. Como está en off (recordad que plt.isinteractive() nos ha dado False, lo que significa que está en ‘off’), si ahora  hacemos lo siguiente (cerrad antes cualquier ventana de gráficos que tengáis abierta):

Vemos que directamente se abre una ventana nueva sin necesidad de llamar a plt.show(). Yo suelo usar IPython así para ir probando cosas y cuando ya acierto con como quiero que me salgan los gráficos voy a spyder, donde tengo el programa que esté haciendo, y ya escribo el código que necesito con la interfaz orientada a objetos.

Jugad un poco con plt.isinteractive(), plt.ion(), plt.ioff(), plt.show() y plt.draw() para estar más familiarizados con el funcionamiento.

[Lo que está en rojo a continuación ya no está disponible en matplotlib 3. Lo dejo por si alguien lo ha enlazado en el pasado para que lo siga encontrando]

Lo siguiente que veremos es plt.hold() y plt.ishold(). plt.hold es un conmutador para decir si queremos que los gráficos se sobreescriban, que en el mismo gráfico tengamos diferentes gráficas representadas, o para que el gráfico se limpie y se dibuje la nueva gráfica cada vez. Si usamos plt.ishold() nos ‘responderá’ True o False. Si acabáis de iniciar sesión, normalmente estará en True.

Y nos devolverá:

Como está en True, si hacemos lo siguiente:

Obtendremos lo siguiente:

Si el modo ‘hold’ estuviera en False, solo se habría conservado el último plot y solo veríamos una línea de las dos (probadlo usando plt.hold() y plt.ishold()).

Si estamos en modo interactivo (plt.ion()) y queremos borrar todos los gráficos (matplotlib.axes.Axes), títulos, …, de la ventana (matplotlib.figure.Figure) podemos usar plt.clf() y nos volverá a dejar el ‘lienzo’ limpio.

Si seguimos en modo interactivo (plt.ion()) y queremos cerrar la ventana podemos usar plt.close().

Imaginaos que ahora queréis trabajar con varias ventanas de gráficos simultáneamente donde en una dibujáis unos datos y en la otra otro tipo de datos y los queréis ver simultáneamente. Podemos hacer esto dándole nombre (o número) a las ventanas con las que vamos a trabajar. Veamos un ejemplo:

Y os quedaría algo como lo siguiente:

Es decir, podemos ir dibujando en varias ventanas a la vez. Podéis probar a cerrar una de las dos ventanas, limpiar la otra, crear una nueva,… Haciendo una llamada a plt.figure() también podemos definir la resolución del gráfico, el tamaño de la figura,…

Pero yo no quiero dibujar los gráficos en dos ventanas, yo quiero tener varios gráficos en la misma. Perfecto, también podemos hacer eso sin problemas con la ayuda de plt.subplot(). Con plt.subplot() podemos indicar el número de filas y columnas que corresponderán a como dividimos la ventana. En el siguiente ejemplo se puede ver dos áreas de gráfico en la misma ventana:

Obteniendo el siguiente gráfico:

Os dejo como ejercicio ver como podéis conseguir la siguiente gráfica (si no sabéis como dejad un comentario) y con ello creo que habréis entendido perfectamente el uso de plt.subplot():

Por último, vamos a ver como configurar la sesión para ahorrarnos escribir código de más. Por ejemplo, imaginaos que queréis que todas las líneas sean más gruesas por defecto porque os gustan más así, que queréis usar otro tipo de fuente sin escribirlo explícitamente cada vez que hacéis un gráfico, que los gráficos se guarden siempre con una resolución superior a la que viene por defecto,… Para ello podéis usar plt.rc(), plt.rcParams, plt.rcdefaults(). En este caso vamos a usar plt.rc(), podréis encontrar más información sobre como configurar matplotlib en este enlace. Veamos un ejemplo para ver como funciona todo esto:

Después de usar plt.rc() para modificar un parámetro esa modificación será para toda la sesión a no ser que lo volvamos a modificar explícitamente o a no ser que usemos plt.rcdefaults(), que devolverá todos los parámetros a los valores por defecto.

Si no has visto el primer capítulo de esta serie échale un ojo ahora o, si prefieres, puedes pasar a la siguiente parte.

11 comentarios en «Manual de introducción a matplotlib.pyplot (II): Creando y manejando ventanas y configurando la sesión»

  1. Hola he intentado hacer el ejercicio de dos arriba y uno abajo. He intentado usar la secuencia :
    (2,2,1) # dos filas dos columnas escribo en el gráfico 1 (imagino que será el gráfico 1,1)
    (2,2,2) #dos filas dos columnas escribo en el gráfico 2 (que imagino que será el gráfico 1,2)
    (2,1,3) # dos filas dos columnas escribo en el gráfico 3 ( pensaba que el 3 se correspondería al de la fila de abajo)
    Esta secuencia me da error, y no entiendo muy bien por que. Gracias

    1. La última te da error porque con (2, 1, 3) estás diciendo «dos filas, una columna, tercer gráfico» (aunque antes hayas dicho que hay dos columnas), pero si hay dos filas y una columna solo tienes los subplots 1 y 2 (de ahí el IndexError). Por tanto (2, 1, 2) te daría el subplot de abajo centrado. Espero que te aclare 🙂

  2. Felicidades por el blog, está súper claro y muy bien elaborado!!!
    soy aprendiz de python y estoy haciendo una simulación sobre el mapa logistico y quiero hacer un zoom para ampliar mi grafica y mostrar que hay iteraciones en los puntos, es decir; que la grafica aumentada en tamaño se verá exactamente igual que a tamaño real, no se si me estoy explicando bien! en fin, me pueden ayudar a modificar mi codigo fuente,para poder amplia el zoom. De antemano muchas gracias!
    from pylab import *
    x = zeros((1600,1000), dtype=’f’)
    x[0][0] = 0.1
    # do the iterations
    for n in range (0,1600):
    x[n][0] = 0.1
    for i in range(1, 1000):
    r = 2.4 + (n/1000.0)
    x[n][i] = r * x[n][i-1]*(1-x[n][i-1])
    x1 = zeros((1600), dtype=’f’)
    for q in range(1, 1600):
    x1[q] = x[q][990]
    x2 = zeros((1600), dtype=’f’)
    for q in range(1, 1600):
    x2[q] = x[q][991]
    x3 = zeros((1600), dtype=’f’)
    for q in range(1, 1600):
    x3[q] = x[q][992]
    x4 = zeros((1600), dtype=’f’)
    for q in range(1, 1600):
    x4[q] = x[q][993]
    x5 = zeros((1600), dtype=’f’)
    for q in range(1, 1600):
    x5[q] = x[q][994]
    x6 = zeros((1600), dtype=’f’)
    for q in range(1, 1600):
    x6[q] = x[q][995]
    x7 = zeros((1600), dtype=’f’)
    for q in range(1, 1600):
    x7[q] = x[q][996]
    x8 = zeros((1600), dtype=’f’)
    for q in range(1, 1600):
    x8[q] = x[q][997]
    r = zeros((1600), dtype=’f’)
    for y in range (0,1600):
    r[y] = 2.4 + (y/1000.0)
    plot(r, x1, ‘g.’, r, x2, ‘g.’, r, x3, ‘g.’, r, x4, ‘g.’, r, x5, ‘g.’, r, x6, ‘g.’, r, x7, ‘g.’, r, x8, ‘g.’)
    title(‘Mapa Logistico’)
    xlabel(‘r’)
    ylabel(‘x’)
    show()

  3. Hola! Por fin pude entender la lógica.
    1-(2,1,1) y (2,1,2) muestra dos axes uno abajo de otro
    2-(1,2,1) y (1,2,2) muestra dos axes uno al lado de otro
    3-(221), (222), (223) y (224) muestra 4 axes, uno en cada esquina
    (recomiendo dibujar en un papel y escribir en cada axes su indice correspondiente)
    para lograr el problema planteado es una combinación de los 1 y 3
    Solucion: (221) (222) y (212) [el indice al ultimo grafico es 212, independientemente de todo lo anterior]
    Otro problema seria dibujar 5 graficos en un figure. 2 de ellos en la primer fila y los otros 3 en la segunda fila
    Solucion: (221),(222),(234),(235) y (236)

  4. analisis de la funcion subplot(): Primero , deacuerdo al problema calculamos el numero de cuadros que va a tener por ejemplo 1 fila y 2 columnas, luego simplemente ubicamos la grafica en uno de los cuadros en este caso solo hay 2 cuadros porque 1 * 2 o filas * columnas va ha ser igual al numero de cuadros ej: plt.subplot(2,2,1) esto dividiria a la ventana en 4 cuadros los 2 primeros parametros corresponde a las filas y columnas respectivamente, y el ultimo a la ubicacion de los cuadros en este caso al primer cuadro de la esquina superior izquierda de la ventana, tambien podemomos hacer convinaciones, siempre y cuando esten en el rango de la division, pues no podemos convinar algo que no tenemos, un ejemplo de convinacion seria plt.subplot(2,1,2) esto se lee: dos filas una columna y cuadro 2 en este caso el cuadro 2 es la segunda fila puesto que solo , tenemos una columna, entonces el 2 cuadro es la 2 fila. espero que esto sea de ayuda.

Responder a Juanlu001 Cancelar la respuesta

Tu dirección de correo electrónico no será publicada.

+ thirty eight = forty four

Pybonacci