sábado, 19 mayo

21:31

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

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. Texto y anotaciones (arrow, annotate, table, text…)
  8. Herramientas estadísticas (acorr, cohere, csd,  psd, specgram, spy, xcorr, …)
  9. Eventos e interactividad (connect, disconnect, ginput, waitforbuttonpress…)
  10. Miscelánea

[Para este tutorial se ha usado python 2.7.1, ipython 0.11, numpy 1.6.1 y matplotlib 1.1.0]

En todo momento supondremos que se ha iniciado la sesión y se ha hecho


import matplotlib.pyplot as plt

import numpy as np

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:

plt.isinteractive()
False

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

plt.plot([1,2,3,4,5])

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

plt.show()

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

plt.ion()
plt.plot([1,2,3,4])

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 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.

plt.ishold()
True

Como está en True, si hacemos lo siguiente:

plt.plot(np.random.rand(10))
plt.plot(np.random.rand(10))
plt.show()

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:

plt.figure('scatter') # Crea una ventana titulada 'scatter'
plt.figure('plot')    # Crea una ventana titulada 'plot'
a = np.random.rand(100) # Generamos un vector de valores aleatorios
b = np.random.rand(100) # Generamos otro vector de valores aleatorios
plt.figure('scatter') # Le decimos que la ventana activa en la que vamos a dibujar es la ventana 'scatter'
plt.scatter(a,b)  # Dibujamos un scatterplot en la ventana 'scatter'
plt.figure('plot') # Ahora cambiamos a la ventana 'plot'
plt.plot(a,b)

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:

plt.ion()  # Nos ponemos en modo interactivo
plt.subplot(1,2,1)  # Dividimos la ventana en una fila y dos columnas y dibujamos el primer gráfico
plt.plot((1,2,3,4,5))
plt.subplot(1,2,2)  # Dividimos la ventana en una fila y dos columnas y dibujamos el segundo gráfico
plt.plot((5,4,3,2,1))

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:

plt.ion()  # Nos ponemos en modo interactivo
plt.figure('valores por defecto')  # Creamos una ventana donde dibujamos el gráfico con la configuración por defecto
plt.suptitle('Titulo valores por defecto')  # Esto sirve para poner título dentro de la ventana
plt.plot((1,2,3,4,5), label = 'por defecto')  # Hacemos el plot
plt.legend(loc = 2)  # Colocamos la leyenda en la esquina superior izquierda

plt.rc('lines', linewidth = 2)  # A partir de aquí todas las líneas que dibujemos irán con ancho doble
plt.rc('font', size = 18)  # A partir de aquí las fuentes que aparezcan en cualquier gráfico en la misma sesión tendrán mayor tamaño
plt.figure('valores modificados')  # Creamos una ventana donde dibujamos el gráfico con la configuración por defecto
plt.suptitle('Titulo valores modificados')  # Esto sirve para poner título dentro de la ventana
plt.plot((1,2,3,4,5), label = u'linea más ancha y letra más grande')  # Hacemos el plot
plt.legend(loc = 2)  # Colocamos la leyenda en la esquina superior izquierda

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 quieres puedes pasar a la siguiente parte.


Filed under: Básico, Tutoriales
FOAF OPML RSS

python-hispano.org

Estado

Estado de fuentes

Archivo

< mayo 2012
lunmarmiéjueviesábdom
30010203040506
07080910111213
14151617181920
21222324252627
28293031010203

Blogs

Actualidad Informatica
Alfffa Solutions
codeplasticlesthack
Dead Epsilon
Django-es
e-ferro
El Atareao
El viaje del navegante
Frogblog
Genbeta:dev
Hyperreals *R
JavAguirre.net
Javier Santana
joe di castro
Monobot
Mundo Python
Pybonacci
Python Insider ES
python majibu
Read The Fucking Docs
Simelo pides...
The::Beastieux
Uno y uno = diez