Introducción a la Computación Matplotlib y otros graficadores Maximiliano Geier Facultad de Ciencias Exactas y Naturales, UBA 5/06/2014 Maximiliano Geier (UBA) Clase 20: Matplotlib y otros graficadores 5/06/2014 1 / 19
Matplotlib Matplotlib Paquete de software libre desarrollado originalmente por John D. Hunter (1968 2012) y cientos de colaboradores voluntarios alrededor del mundo. 0.6 0.4 Pensado como un reemplazo libre del MATLAB hecho en Python. Además, Hunter era un obsesivo y no le gustaban los gráficos de MATLAB, así que los de Matplotlib son (en general) visualmente más atractivos. Como está hecho en Python, se integra fácilmente con otras herramientas de visualización de datos que también están en Python (como el IPython Notebook 1 o Mayavi 2 ). 1.0 0.5 0.0 0.5 0.2 0.0 0.2 0.4 1.0 0.6 0.5 0.0 0.5 1.0 1.0 1 http://ipython.org/notebook.html 2 http://code.enthought.com/projects/mayavi/ Maximiliano Geier (UBA) Clase 20: Matplotlib y otros graficadores 5/06/2014 3 / 19
Matplotlib Matplotlib En lugar de usar su propio lenguaje como MATLAB, los scripts para graficar se escriben enteramente en Python. Tiene un módulo para graficación llamado pylab, que se programa de una manera similar a MATLAB (es una máquina de estados). Para manejar datos hace uso extensivo de la biblioteca de álgebra lineal numpy. Un ejemplo 3 : import matplotlib.pyplot as plt import numpy as np with plt.xkcd(): # Based on "Stove Ownership" from XKCD by Randall Monroe # http://xkcd.com/418/ fig = plt.figure() ax = fig.add_axes((0.1, 0.2, 0.8, 0.7)) ax.spines[ right ].set_color( none ) ax.spines[ top ].set_color( none ) plt.xticks([]) plt.yticks([]) ax.set_ylim([-30, 10]) data = np.ones(100) data[70:] -= np.arange(30) plt.annotate( THE DAY I REALIZED I COULD COOK BACON\nWHENEVER I WANTED, xy=(70, 1), arrowprops={ arrowstyle : -> }, xytext=(15, -10)) plt.plot(data) plt.xlabel( TIME ) plt.ylabel( MY OVERALL HEALTH ) fig.text(0.5, 0.05, "STOVE OWNERSHIP" FROM XKCD BY RANDALL MONROE, ha= center ) 3 http://matplotlib.org/mpl_examples/showcase/xkcd.py Maximiliano Geier (UBA) Clase 20: Matplotlib y otros graficadores 5/06/2014 4 / 19
Matplotlib Hello, world! Vamos a escribir un plot muy sencillo de una función en dos dimensiones. 1 Importamos el módulo de graficación de matplotlib y numpy: import matplotlib.pyplot as plt import numpy as np 2 Construimos vectores para las coordenadas x e y: # como range x = np.arange(0, 2, 0.01) # aplico sin(2π t) a cada elemento # t del vector x y = np.sin(2*np.pi*x) 3 Título y etiquetas para los ejes: plt.title( Hello, world! ) plt.xlabel( tiempo (s) ) plt.ylabel( voltaje (mv) ) 4 Graficamos y en función de x: plt.plot(x, y) 5 Podemos mostrar la figura en pantalla: plt.show() 6 También guardarla en un archivo: plt.savefig( hello.pdf ) voltaje (mv) 1.0 0.5 0.0 0.5 Hello, world! 1.0 0.0 0.5 1.0 1.5 2.0 tiempo (s) Maximiliano Geier (UBA) Clase 20: Matplotlib y otros graficadores 5/06/2014 5 / 19
Matplotlib Cargando datos En general lo que vamos a querer graficar no es una función conocida, sino un conjunto de datos que tenemos guardados en algún lado. Matplotlib nos ofrece (a través de numpy) ciertas comodidades para cargar datos de archivos. 1 Archivos de texto con tuplas de números, una tupla por ĺınea: datos = np.loadtxt( archivo.txt ) # separados por espacios datoscsv = np.loadtxt( archivo.csv, delimiter=, ) # CSV 2 Formato numpy (generado con np.save): datos = np.load( archivo.npy ) 3 Imágenes: img = plt.imread( archivo.png ) 4 Excel: lo más sencillo es exportar los datos de Excel a CSV (desde el mismo Excel). También se puede usar el paquete pandas 4 para cargar planillas de Excel directamente. 4 http://stackoverflow.com/a/17053360 Maximiliano Geier (UBA) Clase 20: Matplotlib y otros graficadores 5/06/2014 6 / 19
Matplotlib Graficando varios sets de datos Supongamos que tenemos un archivo con datos donde cada fila tiene 3 columnas y queremos graficar la segunda en función de la primera y la tercera en función de la primera en un mismo gráfico. 1 En varios plots: datos = np.loadtxt( datos.txt ) plt.plot(datos[:,0], datos[:,1]) plt.plot(datos[:,0], datos[:,2]) 2 Un solo plot: plt.plot(datos[:,0], datos[:,1:]) 3 Si queremos agregar una leyenda describiendo cada curva, tenemos que ponerle un label a cada plot y luego generamos la leyenda: plt.plot(datos[:,0], datos[:,1], label= D&C ) plt.plot(datos[:,0], datos[:,2], label= Fuerza bruta ) plt.legend() Nota de implementación: elegir filas o columnas de un conjunto de datos de numpy se hace por referencia. Esto quiere decir que si modificamos datos[:,0] el cambio también se ve en datos. Si queremos una copia, hay que usar datos[:,0].copy(). Maximiliano Geier (UBA) Clase 20: Matplotlib y otros graficadores 5/06/2014 7 / 19
Matplotlib Cambiando el formato Si no le decimos nada, Matplotlib dibuja con ĺıneas llenas y colores asignados de forma automática, de forma que no se pisen las ĺıneas entre sí. La función plt.plot tiene opciones que permiten configurar cómo se ven las curvas. Algunos ejemplos: # líneas más gruesas de color rojo plt.plot(x, y, color= red, linewidth=2.5) # línea punteada plt.plot(x, y, linestyle= -- ) # color azul y redondeles en cada punto del set de datos plt.plot(x, y, bo ) Tiene muchas opciones. Pueden ver help(plt.plot) Maximiliano Geier (UBA) Clase 20: Matplotlib y otros graficadores 5/06/2014 8 / 19
Matplotlib Cambiando propiedades de los ejes Cuando hacemos un plot nuevo Matplotlib nos setea valores default para los ĺımites de los ejes y los ticks (los valores que muestra sobre cada eje). Estos ĺımites dependen de los valores extremos de los vectores. Si los defaults no se ven bien, los podemos modificar: # ploteamos plt.plot(x, y) # para que se vea un 10% más de valores a cada lado en ambos ejes # (asumiendo que los mínimos son negativos y los máximos positivos) plt.xlim(x.min()*1.1, x.max()*1.1) plt.ylim(y.min()*1.1, y.max()*1.1) # mostramos los valores desde π hasta π en el eje x plt.xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi]) # valores -1, 0 y 1 en el eje y plt.yticks([-1, 0, 1]) Maximiliano Geier (UBA) Clase 20: Matplotlib y otros graficadores 5/06/2014 9 / 19
Matplotlib Usando Matplotlib Matplotlib se puede usar interactivamente desde la consola de Python o desde un programa. Desde la consola normal de Python: mgeier@xpsmax:~$ python3 Python 3.4.0 (default, Apr 11 2014, 13:05:11) [GCC 4.8.2] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import matplotlib.pyplot as plt >>> import numpy as np Desde la consola de IPython: mgeier@xpsmax:~$ ipython3 --pylab Python 3.4.0 (default, Apr 11 2014, 13:05:11) Type "copyright", "credits" or "license" for more information. Using matplotlib backend: TkAgg In [1]: Maximiliano Geier (UBA) Clase 20: Matplotlib y otros graficadores 5/06/2014 10 / 19
Matplotlib Otros tipos de plots 0.030 Histogram of IQ: µ =100, σ =15 35 30 25 Scores Probability 0.020 Histogramas: plt.hist 0.015 0.010 20 15 10 5 0.005 0.000 40 Gra ficos de barra: plt.bar Scores by group and gender Men Women 40 0.025 0 60 80 100 120 Smarts 140 160 Logs Frogs A 0.25 B C Group D E Volume and percent change 0.20 15.0% 10.0% 0.15 i +1 0.10 Gra ficos de torta: plt.pie Hogs 30.0% 45.0% Dogs 0.05 0.10 0.15 0.15 0.10 0.05 0.00 0.05 0.10 0.15 0.20 0.25 i Scatter plot (puntos sobre un plano): plt.scatter Superficie 3D: plt.plot_surface 2 6 4 0 20 2 4 2 4 6 6 Maximiliano Geier (UBA) 0.05 0.00 Clase 20: Matplotlib y otros graficadores 1.01 0.79 0.56 0.34 0.11-0.11-0.34-0.56-0.79-1.01 6 4 0.8 0.6 0.4 0.2 0.0 0.2 0.4 0.6 0.8 2 6 4 0 2 0 2 4 2 4 6 6 5/06/2014 4 1.0 0.6 0.2 0.2 0.6 1.0 6 11 / 19
Gnuplot Gnuplot Uno de los primeros sistemas de graficación scripteables. Desarrollado originalmente por Colin Kelly y Thomas Williams en 1986. Actualmente es el más usado de los graficadores de este tipo, funciona en la mayoría de los sistemas operativos. Varios programas lo utilizan como motor de graficación (por ejemplo QtiPlot). A diferencia de Matplotlib, usa su propio lenguaje especializado en graficar figuras. Soporta salidas en distintos formatos por medio de sus muchos terminal drivers: qt, canvas, svg, pdf, png, tikz, latex, windows, etc. Maximiliano Geier (UBA) Clase 20: Matplotlib y otros graficadores 5/06/2014 13 / 19
Gnuplot Hello, world! Vamos a ver cómo se escribe el mismo plot de antes en gnuplot: 1 Título y textos de los ejes: set title "Hello, world!" set xlabel "tiempo (s)" set ylabel "voltaje (mv)" 2 Rango del eje X: set xrange [0:2] 3 Graficamos: plot sin(2*pi*x) 4 (Opcional) Si queremos guardar la figura en un PDF: set term pdf set output "figura.pdf" replot voltaje (mv) 1 0.8 0.6 0.4 0.2 0-0.2-0.4-0.6-0.8-1 Hello, world! 0 0.5 1 1.5 2 tiempo (s) Nota de implementación: la salida a PDF no guarda el archivo hasta que no es cerrado. Se puede forzar su cierre con set output sin ningún nombre. sin(2*pi*x) Maximiliano Geier (UBA) Clase 20: Matplotlib y otros graficadores 5/06/2014 14 / 19
Gnuplot Graficando datos de un archivo Volvamos al ejemplo del archivo de datos con 3 columnas. Si queremos repetir el mismo plot en gnuplot, podemos cargar los datos directamente desde el comando plot: plot datos.txt using 1:2 with lines title D&C, \ datos.txt using 1:3 with lines title Fuerza bruta plot: soporta varios argumentos separados por comas, cada uno es una función o conjunto de puntos a graficar. using N:M: usa las columnas especificadas del dataset. with lines: plotear un conjunto de puntos predeterminadamente nos marca solo los puntos. title <texto>: pone <texto> como label de ese conjunto de datos o función. Al igual que en Matplotlib, la función plot tiene muchos modificadores para cambiar la apariencia de los gráficos. Maximiliano Geier (UBA) Clase 20: Matplotlib y otros graficadores 5/06/2014 15 / 19
Gnuplot Usando gnuplot Gnuplot se puede usar interactivamente o en modo batch. En el modo interactivo escribimos los comandos en la consola. mgeier@xpsmax:~$ gnuplot G N U P L O T Version 4.6 patchlevel 4 last modified 2013-10-02 Build System: Linux x86_64 Terminal type set to wxt gnuplot> En el modo batch escribimos un script con todos los comandos y luego gnuplot los lee ĺınea por ĺınea. mgeier@xpsmax:~$ gnuplot hello.gpi Maximiliano Geier (UBA) Clase 20: Matplotlib y otros graficadores 5/06/2014 16 / 19
Otros graficadores Otros graficadores scripteables Software libre: GNU Octave: alternativa libre al MATLAB, usa un formato de scripting bastante compatible. R: paquete estadístico, lenguaje propio orientado a objetos. ROOT: paquete de análisis de datos desarrollado en CERN, se programa en C++ (también orientado a objetos). Software propietario: MATLAB: lenguaje propio (imperativo). Origin: lenguaje propio (imperativo). SAS: lenguaje propio. SPSS: lenguaje propio, también se puede usar desde Python y VB.NET. Maple: lenguaje propio (imperativo). Lista completa: http://en.wikipedia.org/wiki/list_of_graphing_software Maximiliano Geier (UBA) Clase 20: Matplotlib y otros graficadores 5/06/2014 18 / 19
Otros graficadores Referencia adicional Tutorial de Matplotlib: http://www.loria.fr/~rougier/teaching/matplotlib/ Ejemplos 2D: http://matplotlib.org/users/screenshots.html Ejemplos 3D: http://matplotlib.org/examples/mplot3d/index.html#mplot3d-examples-index Guía de usuario (Matplotlib): http://matplotlib.org/matplotlib.pdf Guía de usuario (NumPy): http://docs.scipy.org/doc/numpy/numpy-ref-1.8.1.pdf Stackoverflow: http://stackoverflow.com/questions/tagged/matplotlib NumPy for Matlab Users: http://wiki.scipy.org/numpy_for_matlab_users Ejemplos de gnuplot: http://gnuplot.sourceforge.net/demo/ Guía de usuario (gnuplot): http://gnuplot.sourceforge.net/docs_cvs/gnuplot.pdf gnuplot Quick Reference: http://www.gnuplot.info/docs_4.0/gpcard.pdf Maximiliano Geier (UBA) Clase 20: Matplotlib y otros graficadores 5/06/2014 19 / 19