Una breve introducción a Matplotlib Pedro Jorge De Los Santos © 2016 Pedro Jorge De Los Santos
También por Pedro Jorge De Los Santos De MATLAB a Python Programación en MATLAB, fundamentos y aplicaciones
A la memoria de John Hunter, al equipo de desarrollo de Matplotlib y toda la comunidad del Scientific Python.
ÍNDICE GENERAL
Índice general Aquí comenzamos… . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1
Una primera aproximación: utilizando pylab . . . . . . . . . . . . . . . . . . . . . . . . . .
2
Lo que hay que saber de NumPy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10
Creando arrays en Numpy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10
Pyplot y lo básico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
12
Coordenadas rectangulares . . . . . . . Etiquetas básicas (xlabel, ylabel & title) Estilos, colores y grosores de líneas . . . Coordenadas polares . . . . . . . . . . . Scatter Plots . . . . . . . . . . . . . . . Gráficas de barras . . . . . . . . . . . . Gráficas de pastel . . . . . . . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
Versión incompleta
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. 13 . 15 . 16 . 19 . 20 . 20 . 20
1
Aquí comenzamos…
Aquí comenzamos… Matplotlib es una librería de Python para el trazo de gráficas, desarrollada inicialmente por John Hunter. Tiene una sintaxis inspirada en MATLAB y comparte mucha similitud en las principales funciones, aunque Matplotlib permite un desarrollo de gráficas utilizando el enfoque orientado a objetos, lo cual le convierte en una herramienta muy potente.
Versión incompleta
2
Una primera aproximación: utilizando pylab
Una primera aproximación: utilizando pylab Este primer capítulo tiene como objetivo mostrar algunas de las capacidades de Matplotlib de manera breve y un tanto superficial , utilizando la interfaz de pylab, esto para familiarizar al lector con la sintaxis y el uso de algunas funciones elementales. El módulo pylab integra las capacidades gráficas de Matplotlib con algunas utilidades de NumPy, proporcionando de esta manera una interfaz muy parecida a MATLAB para el manejo de gráficas. En este capítulo vamos a suponer que, antes de todo, se ha importado pylab de la siguiente manera: 1 from pylab import *
Lo anterior nos permitirá disponer de todas las funciones de pylab dentro de nuestro script. Luego, graficar nuestro primer ejemplo será tan sencillo como escribir. 1 plot([1,-2,5,-2,1, 0,3]) 2 show()
Versión incompleta
3
Una primera aproximación: utilizando pylab
La función plot, en el caso anterior, recibe como argumento un arreglo de valores numéricos, que puede ser un lista de Python ordinaria, una tupla, y de manera más común un array de NumPy. La función show permite mostrar en pantalla la linea o gráfica que se ha creado con plot. Ahora, como se ha mencionado, pylab también permite utilizar funciones de NumPy para la definición de arrays. Por ejemplo, con linspace podemos crear un vector de valores numéricos: 1 linspace(a,b,n)
Siendo a el extremo inferior, b el extremo superior, y n el número de particiones en el intervalo [a, b]. Por ejemplo: 1
>>> linspace(1,10,10)
2 array([
1.,
2.,
3.,
4.,
5.,
6.,
7.,
8.,
9.,
10.])
Luego, a estos arrays de NumPy podemos aplicarles funciones matemáticas predefinidas, por ejemplo: Versión incompleta
4
Una primera aproximación: utilizando pylab 1
>>> x = linspace( 0,2*pi,10)
2
>>> y = cos(x)
3
>>> x
4 array([ 0. 5
6
>>> y
3.4906585 , 4.1887902 , 4.88692191, 5.58505361, 6.28318531])
7 array([ 1. 8
, 0.6981317 , 1.3962634 , 2.0943951 , 2.7925268 ,
, 0.76604444, 0.17364818, -0.5
-0.93969262, -0.5
, -0.93969262,
, 0.17364818, 0.76604444,
1.
Con lo anterior crearemos nuestra primer gráfica de una función matemática: 1
x = linspace( 0,10)
2
y = cos(x)
3 plot(x,y) 4 show()
Versión incompleta
])
5
Una primera aproximación: utilizando pylab
Note que a linspace no le hemos indicado el número de particiones del intervalo, con lo cual se toma por default un valor de 50. Podemos cambiar el color y estilo de línea pasando una cadena de dos caracteres como tercer argumento, donde el primer caracter indica el color y el segundo el símbolo a utilizar, por ejemplo: 1
x = linspace( 0,10)
2
y = cos(x)
3 plot(x,y,"ro") 4 show()
Puede consultar los caracteres válidos para el color y estilo de línea en la documentación de la función plot¹. Es posible también especificar el color y estilo utilizando keyword arguments² dentro de la función plot: ¹http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.plot ²https://docs.python.org/2/tutorial/controlflow.html#keyword-arguments Versión incompleta
6
Una primera aproximación: utilizando pylab 1 plot(x,y,linestyle="--",color="k")
Además, el color también puede especificarse utilizando la notación RGBA y la notación hexadecimal, por ejemplo, las siguientes instrucciones son equivalentes: 1 plot(x,y,color="r") 2 plot(x,y,color="#FF0000") 3 plot(x,y,color=(1, 0, 0,1))
Podemos incluir etiquetas en los ejes utilizando las funciones xlabel y ylabel. Por ejemplo: 1
K = 525
2
n = 0.2
3
e = linspace( 0, 0.5)
4
s = K* e**n;
5 plot(e,s,'m') 6 xlabel(u"Deformación (mm/mm)") 7 ylabel(u"Esfuerzo (MPa)") 8 show()
Versión incompleta
7
Una primera aproximación: utilizando pylab
Incluso se puede utilizar código TeX en las etiquetas y título de la gráfica: 1
K = 525
2
n = 0.2
3
e = linspace( 0, 0.5)
4
s = K* e**n;
5 plot(e,s,'m') 6 xlabel(r"$\varepsilon$ (mm/mm)") 7 ylabel(r"$\sigma$ (MPa)") 8 title(r"Acero SAE 1008: $\sigma = K \varepsilon^n$") 9 show()
Versión incompleta
8
Una primera aproximación: utilizando pylab
Para poder graficar en dos o más axes se puede utilizar la función subplot que permite crear un arreglo de axes, véase el ejemplo a continuación: 1
t = linspace( 0,2)
2
x = 12*t**3 - 18*t**2 + 2*t + 5
3
v = diff(x)
4
# Gráfica de posición
5 subplot(2,1,1) 6 plot(t,x,"b") 7 ylabel(u"Posición (m)") 8
# Gráfica de velocidad
9 subplot(2,1,2) 10 plot(t[:-1],v,"g") 11 xlabel("Tiempo (s)") 12 ylabel(u"Velocidad (m/s)") 13 show()
Versión incompleta
9
Una primera aproximación: utilizando pylab
Múltiples axes
La función subplot recibe tres argumentos, los dos primeros especifican el número de filas y columnas del arreglo de axes, respectivamente, y el tercer argumento indica la posición del axes a utilizar. La función diff³ calcula la n-ésima derivada numérica de un vector dado. ³http://docs.scipy.org/doc/numpy-1.10.0/reference/generated/numpy.diff.html
Versión incompleta
10
Lo que hay que saber de NumPy
Lo que hay que saber de NumPy NumPy es una librería de de uso muy extendido en la comunidad técnico-científica de Python, es imprescindible y un estándar para situaciones en las cuales se manejan datos en forma de vectores o matrices. Claro está que para graficar en Matplotlib no es estrictamente necesario utilizar arrays de NumPy, sino cualquier elemento iterable que pueda contener valores numéricos. Pero es evidente que los arrays de NumPy proporcionan una ventaja enorme cuando se manejan datos que requieren cierto procesamiento mediante herramientas matemáticas. En este capítulo se tratarán funciones básicas de NumPy que permiten crear y modificar arrays, que luego se usarán para representarlos en Matplotlib.
Creando arrays en Numpy Primero, vamos a suponer que para todas las instrucciones subsecuentes, antes se ha importado el módulo NumPy utilizando el alias np, como sigue: 1
>>> import numpy as np
La manera básica de crear un array es utilizando la función np.array, a la cual se debe pasar como argumento una lista de valores numéricos para definir un vector o bien una lista de listas para definir matrices, por ejemplo: 1
>>> X=np. array([1,2,3])
Lo anterior crea un objeto de la clase numpy.ndarray 1
>>> type(X)
2
Para definir una matriz A dada por:
1 A = 4
2 3 5 6 7 8 9
se tiene que pasar una lista de listas como argumento, donde cada sublista representa una fila de la matriz: Versión incompleta
11
Lo que hay que saber de NumPy 1
>>> A=np. array([[1,2,3],[4,5, 6],[7, 8, 9]])
2
>>> A
3 array([[1, 2, 3], 4
[4, 5, 6],
5
[7, 8, 9]])
Esta es la forma manual de crear un array en NumPy, definiendo uno a uno los elementos, lo cual resultaría pesado en arreglos de grandes dimensiones. NumPy proporciona algunas funciones que permiten crear arrays con valores que siguen un patrón especifico, por ejemplo, valores en un intervalo [a, b] con incrementos n, o bien cierta cantidad de elementos en un rango, o incluso arreglos de ceros y unos. La función que más usaremos en este texto será linspace, la cual permite crear un array de un cierto número de elementos en un intervalo fijo. Por ejemplo: 1
>>> np.linspace(2,10,5)
2 array([
2.,
4.,
6.,
8.,
10.])
Lo anterior crea un array de 5 elementos en el intervalo [2, 10]. Otra función muy similar es arange, la cual también necesita como argumentos los extremos del intervalo, pero en lugar del número de elementos se indica el paso o incremento. 1
>>> np. arange(2,10,2)
2 array([2, 4, 6, 8])
Note que arange no incluye el extremo superior, es decir, toma los valores del intervalo abierto por la derecha [a, b).
Versión incompleta
12
Pyplot y lo básico
Pyplot y lo básico En el Capítulo 2 vimos una introducción a pylab, un módulo de matplotlib que integra las utilidades gráficas del módulo pyplot y de la librería NumPy en un mismo espacio de nombres . El uso de pylab hace recordar mucho la sintaxis y la filosofía de programación de MATLAB. Por ello (y por razones que iremos conociendo posteriormente) en el entorno de Matplotlib es preferible utilizar pyplot y NumPy cómo módulos independientes, permitiendo una estructuración más limpia de código, diferenciando la parte de proceso de datos y la de graficación/visualización. Un código típico utilizando pylab sería: 1 from pylab import * 2 3
x = linspace( 0,10)
4
y = cos(x)
5 6 plot(x,y,lw=2,ls="--") 7 xlabel("Tiempo (s)") 8 ylabel("Amplitud (mm)") 9 show()
¿Y utilizando pyplot + NumPy? 1 import matplotlib.pyplot as plt 2 import numpy as np 3 4
x = np.linspace( 0,10)
5
y = np.cos(x)
6 7
plt.plot(x,y,lw=2,ls="--")
8
plt. xlabel("Tiempo (s)")
9
plt. ylabel("Amplitud (mm)")
10
plt. show()
Ambos códigos producen exactamente lo mismo. Ahora veremos una tercera forma (mejorada ) de hacer lo anterior:
Versión incompleta
13
Pyplot y lo básico 1 import matplotlib.pyplot as plt 2 import numpy as np 3 4
x = np.linspace( 0,10)
5
y = np.cos(x)
6 7
fig = plt.figure()
8
ax = fig. add_subplot(111)
9 10
ax.plot(x,y,lw=2,ls="--")
11
ax. set_xlabel("Tiempo (s)")
12
ax. set_ylabel("Amplitud (mm)")
13 14
plt. show()
Y sí, en este texto vamos a utilizar esta manera de hacer las cosas, ¿la diferencia?: objetos, métodos y esas cosas propias de la programación orientada a objetos, que nos permitirá organizar nuestro código de una mejor manera, sobre todo cuando este tiende a ser extenso. De manera breve, lo que se hace es instanciar un objeto de la clase Figure, que es básicamente el objeto gráfico principal o lo que denominaríamos como ventana , y posteriormente se utilizan métodos de clase para crear un Axes y utilizar sus métodos para trazar la gráfica correspondiente y las etiquetas o leyendas necesarias. Para las secciones siguientes se asumirá que en todo momento se han importado el módulo pyplot y NumPy y que al final del código se ha incluido la instrucción plt.show() para mostrar lo que se ha graficado. 1 import matplotlib.pyplot as plt 2 import numpy as np 3
# .
4
# .
5
# .
6
plt. show()
Coordenadas rectangulares Hemos estado utilizando este tipo de gráficas en todos los ejemplos anteriores, entendemos por coordenadas rectangulares aquellas en donde cada punto del plano o espacio está dado por sus coordenadas (x,y) o (x,y,z) y las cuales hemos tenido hasta en la sopa desde nuestro primer curso de álgebra en el nivel secundario. Por ahora vamos a tomar el caso bidimensional, y en la mayoría de situaciones vamos a graficar un array que contiene los valores de la variable independiente (digamos x ) contraun array que contiene los valores de la variable dependiente (digamos f(x) ), utilizando, claro está, la función plot. Versión incompleta
14
Pyplot y lo básico
Por ejemplo supongamos que queremos graficar la función f (x) = x 2 sin(x) en el intervalo [0, 2π ]. Primero debemos crear el vector o array de la variable independiente en el intervalo de interés, para ello podemos utilizar linspace: 1
x = np.linspace( 0,2*np.pi)
Enseguida definimos el array de la función o variable dependiente: 1
y = (x**2)*(np. sin(x))
Ahora creamos el objeto figure: 1
fig = plt.figure()
Utilizando el método add_subplot del objeto fig creamos el axes a utilizar: 1
ax = fig. add_subplot(111)
Con nuestro axes creado, podemos utilizar el método plot para trazar la gráfica correspondiente: 1
ax.plot(x, y)
Finalmente debemos utilizar la instrucción plt.show() para mostrar las gráficas que hemos generado. Juntando todo el código anterior se tiene: 1
x = np.linspace( 0,10)
2
y = np.cos(x)
3 4
fig = plt.figure()
5
ax = fig. add_subplot(111)
6 7
ax.plot(x, y)
Versión incompleta
15
Pyplot y lo básico
Etiquetas básicas (xlabel, ylabel & title) Naturalmente una gráfica sin información extra más que las líneas trazadas es inútil desde donde se vea, porque cuando vamos a graficar algo el objetivo es transmitir información legible y en cierto punto amigable a terceros. Para ello en una gráfica se debe incluir información acerca de los datos que estamos representando. En casi cualquier gráfica que veamos en libros, artículos o cualquier otro tipo de publicación vamos a tener al menos etiquetados los ejes coordenados, y una título o pequeña descripción que muestre lo que se representa. Para colocar esa información básica en una gráfica, Matplotlib proporciona los métodos set_xlabel, set_ylabel y set_title de la clase Axes, que de manera respectiva, colocan una etiqueta en el eje horizontal, una etiqueta en el eje vertical y un título en la parte superior del Axes. En el siguiente código se muestra cómo colocar las etiquetas mencionadas anteriormente:
Versión incompleta
16
Pyplot y lo básico 1
T = [50, 60, 70, 80, 90, 100, 110, 120]
2
P = [12, 20, 33, 54, 90, 148, 244, 403]
3 4
fig = plt.figure()
5
ax = fig. add_subplot(111)
6 7
ax.plot(T, P)
8
ax. set_xlabel(u"Temperatura (°C)")
9
ax. set_ylabel(u"Presión (KPa)")
10
ax. set_title(u"Relación P-T")
Estilos, colores y grosores de líneas Estilizar líneas es una cuestión muy común, puesto que muchas veces es necesario diferenciar una serie de datos de otra mediante su aspecto. Para ello Matplotlib dispone de algunas utilidades para proporcionar grosores, colores y estilos a una línea. Existen cuatro estilos de líneas en Matplotlib: sólida, discontinua, de guión-punto y punteada. Estos estilos pueden establecerse mediante el keyword argument linestyle.
Versión incompleta
17
Pyplot y lo básico 1
x = np.linspace( 0,10)
2
y = np.cos(x)
3 4
fig = plt.figure()
5
ax = fig. add_subplot(111)
6 7
ax.plot(x, y, linestyle="-")
8
ax.plot(x, y+1, ls="--")
9
ax.plot(x, y+2, ls="-.")
10
ax.plot(x, y+3, ls=":")
Note que el keyword argument linestyle puede abreviarse como ls y sigue funcionando correctamente. Los colores de una línea pueden indicarse utilizando el keyword argument color y pasándole en este una cadena hexadecimal o bien una tupla de tres valores con los valores correspondientes al modelo RGB.
Versión incompleta
18
Pyplot y lo básico 1
x = np.linspace( 0,10)
2
y = np.cos(x)
3 4
fig = plt.figure()
5
ax = fig. add_subplot(111)
6 7
ax.plot(x, y, color=( 0,1,1))
8
ax.plot(x, y+1, color="#ff00ff")
El grosor de una línea se establece mediante el argumento linewidth o su forma abreviada lw . 1
x = np.linspace( 0,10)
2
y = np.cos(x)
3 4
fig = plt.figure()
5
ax = fig. add_subplot(111)
6 7
ax.plot(x, y, lw=2)
8
ax.plot(x, y+1, lw=4)
9
ax.plot(x, y+2, linewidth=6)
Versión incompleta
19
Pyplot y lo básico
Tanto el color (con ciertas limitaciones) como el estilo pueden especificarse como un tercer argumento en el método plot sin necesidad de utilizar keyword arguments : 1
ax.plot(x, y, "r--")
Donde lo anterior le indica a Matplotlib que debe trazar una línea discontinua de color rojo. Sin embargo está limitado a unos cuantos colores predeterminados que puede encontrar en la siguiente referencia⁴.
Coordenadas polares Para trazar gráficas en coordenadas polares en Matplotlib se utiliza también el método plot, pero cuando se crea el axes debemos cambiar el tipo de proyección que utilizaremos a coordenadas polares, lo cual puede hacerse de las utilizando el keyword argument projection: 1
fig = plt.figure()
2 polar_axes = fig. add_subplot(111, projection="polar")
O bien utilizando polar:
⁴http://matplotlib.org/api/colors_api.html Versión incompleta
20
Pyplot y lo básico 1
fig = plt.figure()
2 polar_axes = fig. add_subplot(111, polar=True)
Por ejemplo, trazando la rosa polar r (θ) = 0.25 cos (3θ): 1 theta = np.linspace( 0,2*np.pi,1000) 2
r = 0.25*np.cos(3*theta)
3 4
fig = plt.figure()
5
ax = fig. add_subplot(111, polar=True)
6 7
ax.plot(theta, r)
Scatter Plots Gráficas de barras Gráficas de pastel
Versión incompleta