7ar2020 Jupyter Notebook Viewer
Matplotlib - graficos 2D y 3D en Python
ht
JNdml.riken.,jp/~rob/
:ldml.riken jp/=rob/)
Traducido/Adaptado por G.F. Rubilar (httes://g00gle.com/+GuillermoRubilar).
La tiltima versién de estos notebooks de [Python (https:
httpy/github.com/gfrubilclases:
fhon.orginotebook.htm!) esta disponible en
ython-cientifico (htips://github. com/gfrubilclases-python-cientifico).
La ultima versién del original (en inglés) de estos notebooks de IPython
‘esté disponible en http:/github.com/jrjohansson/scientific-python-lectures
(https://github.com/rjohansson/scientific-python-lectures)
ps:/ipython.orginotebook. html)
Los otros notebooks de esta serie estan listados en http:/rjohansson_github.com
(https:l/rjohansson github,com),
Introducci6n
Matplotib es una excelente libreria grafica 2D y 3D. Algunas de las muchas ventajas de esta libreria son:
Es facil comenzar a crear graficos.
Incluye soporte para $\LaTeX$ en leyendas y textos.
+ Mucho control de cada elemento de la figura, incluyendo el tamafio y la densidad de puntos (DPI).
Formats de salida de alta calidad, incluyendo PNG, PDF, SVG, EPS.
GUI para la exploracién interactiva de figuras y soporte para la generacién “headless” de archivos de
figuras.
Una de las caracteristicas claves de Matplotiib y que hace a Matplotiib altamente adecuado para generar
figuras para publicaciones cientificas es que todos los aspectos de la figura pueden ser controlados en
programando. Esto es imporante para la reproducibilidad y conveniente cuando se necesita regenerar la
figura con datos actualizados 0 cambios en su apariencia
Mas informacién en la pagina de Matpiotiib: http:/matplottib.org/_(https://matplotib.ora/)
La API orientada al objeto de Matplotlib
La idea principal de la programacién orientada al objeto is que se tienen objetos sobre los cuales se
pueden aplicar funciones (métodos) y acciones, y que ningin estado de un objeto o programa debe ser
global (tal como en la API tipo MATLAB). La ventaja de esta forma de trabajo se manifiesta cuando se
requiere crear més de una figura, o cuando una figura contiene sub-figuras.
Para usar la API orientada al objeto comenzamos similarmente al ejemplo anterior, pero en lugar de crear
Una instancia de figura global almacenamos una referencia a la figura recién creada en la variable fig. y
a partir de ella creamos nuevos ejes axes usando el método add_axes enlainstancia fig dela clase
Figure
hitps:Inoviewer upyter.orglurls/d.dropbox.convslatSranéocZgakmSPytnon05_Matplotibipynb 317ar2020 -Jupyter Notebook Viewer
In [1]:
Ymatplotlib inline
import pylab as pl
import numpy as np
x = np. linspace(@,5,5@)
y = xt#2
Fig = pl.figure()
ejes =
fig-add_axes([@.1, 0.1, @.8, @.8]) # izquierda, abajo, ancho, altura (rango 0 a
ejes.plot(x,y,"r")
ejes.set_xlabel('x')
ejes.set_ylabel(‘y')
ejes.set_title(u'Titulo');
Titulo
%
20
6
‘Aunque se requiere algo mas de cédigo, la ventaja es que ahora tenemos control completo sobre dénde
se ubican los ejes, y ademas podemos agregar facilmente mas de un eje ala figura
hitps:Inoviewer upyter.orglurls/d.dropbox.convslatSranéocZgakmSPytnon05_Matplotibipynb 26172020 -Jupyler Notebook Viewer
In [2]:
Fig = pl.figure()
axes1 = fig.add_axes([@.1, @.1,
2, 0.5,
2.8, 0.8]) # ejes principales
axes2 = fig.add_axes((@.2, 0.5, 0.4, 0.3
8 ]
4, 0.3]) # ejes del grafico insertado
# Figura principal
axesi.plot(x,y,'r')
axesi.set_xlabel (‘x")
axes1.set_ylabel('y')
axesi.set_title(u'Titulo principal’)
# Figura insertada
axes2.plot(y,x,'g')
axes2. set_xlabel(‘y")
axes2. set_ylabel ("x")
axes2.set_title(u'Titulo secundario');
Titulo principal
2%
lo secundario
2»
0
Si no nos importa ser explicitos sobre dénde estarén ubicados los ejes en el marco de nuestra figura,
podemos usar uno de los muchos administradores de la distribucién de los ejes que tiene Matplotlib. Uno
favorito es subplots , que puede ser usado de la forma siguiente:
hitps:Inoviewer upyter.orglurls/d.dropbox.convslatSranéocZgakmSPytnon05_Matplotibipynb
ast7212020 -Jupyler Notebook Viewer
In [3]:
Fig, axes = pl.subplots() # crea una nueva figura y un set de ejes
axes .plot(x,y,'r")
axes. set_xlabel(‘x")
axes.set_ylabel(‘y')
axes.set_title(u'Titulo');
Titulo
2%
2
10
In [4]:
# crea una figura, con dos set de ejes, almacenados en el array axes
fig, axes = pl.subplots(nrows=1, ncols=2)
for ax in axes:
ax.plot(x, ys 'n')
ax. set_xlabel (r'$x_'tstr(i)+"$")
ax. set_ylabel(r'$y_'+str(i)+"$")
ax, set_title(u'Titulo '+str(i))
it=15
Titulo 1 Titulo 2
2% B
20 »
6 6
»
Facil, pero no tan bonito debido a la superposicién de los ejes y etiquetas en la parte central, cierto?
Podemos mejorar esto usando el método fig. tight_Layout , que ajusta automdticamente la posicién
de los ejes en el marco de la figura de modo que no exista contenido que se superponga
hitps:Inoviewer upyter.orglurlsid.dropbox.convslafSranéocZgakmSPytnon05_Matplotibipynb
4017ar2020 -Jupyter Notebook Viewer
In [5]:
fig, axes = pl.subplots(nrows=1, ncols=2)
ist
for ax in axes:
ax.plot(x, ys 'n')
ax.set_xlabel(r'$x_'+str(i)+"$")
ax.set_ylabel(r’$y_'+str(i)#"$")
ax.set_title(u'Titulo '+str(i))
itet
fig. tight_layout()
Titulo 1 itulo 2
2% ro
20 20
5 5
10 wo
5 5
° °
0 2 a o 2 a
Tamaiio de la figura, proporcién de los ejes y DPI
Matpiotiib permite especificar la proporcién de los ejes, la densidad de puntos (DPI) y el tamafio de la
figura cuando el objeto Figure es creado, usando los argumentos figsize y dpi. figsize es una
tupla con el ancho y la altura de la figura en pulgadas, y dpi es el ntimero de puntos (pixels) por
pulgada, Para crear una figura de 800 por 400 pixels podemos usar:
In [7]:
fig = pl.figure(figsiz
8,4), dpi=100)
Los mismos argumentos pueden ser usados en los administradores de distribucién de ejes, como
subplots
hitps:Inoviewer upyter.orglurls/d.dropbox.convslatSranéocZgakmSPytnon05_Matplotibipynb 50317212020 -Jupyler Notebook Viewer
In [8]:
Fig, axes = pl.subplots(figsize=(12,3))
axes.plot(x, ys 'r')
axes. set_xlabel('x")
axes.set_ylabel(‘y')
axes.set_title(u'Titulo');
Titulo
Guardando figuras
Para guardar una figura en un archivo podemos usar el método savefig enlaclase Figure
In [9]:
Fig. savefig("archivo. png")
Podemos, en forma opcional, especificar los DPI, ademds de elegir entre varios formatos.
In [10]:
fig.savefig("archivo.png", dpi=200)
In [11]:
Fig. savefig("archivo. svg")
~Qué formatos estan disponibles y cuales deberian ser usados para objener
la mejor calidad?
Matplotiib puede crear graficos de alta calidad en varios formatos, incluyendo PNG, JPG, EPS, SVG y
PDF. Para publicaciones cientificas, se recomienda usar PDF donde sea posible (y compilar documentos
LaTeX con pdflatex , que puede incluir las figuras en PDF usando el comando includegraphics
hitps:Inoviewer upyter.orglurls/d.dropbox.convslatSranéocZgakmSPytnon05_Matplotibipynb 317ar2020 -Jupyter Notebook Viewer
Leyendas, etiquetas y titulos
‘Ahora que hemos cubierto lo basico de cémo generar un marco de figura y agregar ejes al marco, veamos
‘c6mo decorar una figura con titulos, etiquetas de ejes y leyendas:
Titulos de figura
Se puede agregar un titulo a cada instancia de ejes de una figura. Para definir el titulo usamos el método
set_title enla instancia de ejes:
In [12]:
ax. set_title(u"Titulo")
out[12]:
Etiquetas de ejes
Similarmente, usandos los métodos set_xlabel y set_ylabel podemos definir las etiquetas de los
ejes Xe Y:
In [13]:
ax. set_xlabel("x")
ax. set_ylabel("y")
out(13]:
Leyendas
Las leyendas de las curvas (o puntos, etc.) de una figura pueden ser agregados de dos maneras.
Podemos usar el método legend de un eje y pasarle una lista/tupla de textos de lygendas para las
‘curvas que ya han sido creadas previamente:
In [14]:
ax.legend(["curvai", “curva2", “curva3"]);
Este método sigue la API de MATLAB. Tiende a inducir a error y es poco flexible si se agregan 0 eliminan
‘curvas de una figura (y como resultado se obtienen leyendas erroneamente asociadas a las curvas)
Es mejor usar los argumentos label="texto” cuando se agregan gréficos u otros objetos a la figura, y
luego usar el método Legend sin argumentos para agregar las leyendas:
hitps:Inoviewer upyter.orglurls/d.dropbox.convslatSranéocZgakmSPytnon05_Matplotibipynb 7017ar2020
In [15]:
-Jupyter Notebook Viewer
ax.plot(x, x*#2, label="curval’
ax.plot(x, x**3, labe:
ax. legend();
La ventaja de este método es que si se agregan o eliminan curvas a una figura, las leyendas se actualizan
automaticamente.
Lafuncién legend acepta el argumento adicional loc que puede ser usado para especificar dénde se
ubicard la leyenda en la figura. Los valores permitidos para loc son ntimeros que codifican los distintos,
lugares donde puede ser ubicada la leyenda, Ver http:/imatplotlib.org/usersilegend_guide.htmi#legend-
location (https://matplotlib org/users/legend_guide.htmitlegend-location) para mas detalles. Las
alternativas mas comunes son
In [16]:
ax.legend(loc=@) # deja que Matplotlib decida La ubicacidn dptima
ax.legend(loc=1) # esquina
ax.legend(loc=2) # esquina
ax.legend(loc=3) # esquina
ax.legend(loc=4) # esquina
# .. muchas otras opciones
Out [16]:
superior derecha
superior izquierda
inferior izquierda
inferior derecha
disponiles
La siguiente figura muestra cémo usar los titulos, etiquetas de ejes y leyendas descritas anteriormente:
hitps:Inoviewer upyter.orglurls/d.dropbox.convslatSranéocZgakmSPytnon05_Matplotibipynb
317ar2020 -Jupyter Notebook Viewer
In [17]:
fig, ax = pl.subplots()
ax.plot(x, x**2, labe
ax.plot(x, x**3, labe
ax.set_xlabel(‘x')
ax.set_ylabel('y')
ax.set_title(u'Titulo')
ax.legend(loc=2); # esquina superior izquierda
xA2$"),
xA3$"),
Titulo
120
100
Formateando texto: LaTeX, tamafio de letras, familia del tipo de
letra
La figura anterior es funcional, pero (atin) no satisface los criterior para una figura usada en una
publicacién. Primero, necesitamos tener texto formateado en LaTeX, y ademas necesitamos poder ajustar
el tamajfio de las letras que aparecen en la publicacién.
Matplotib tiene un muy buen soporte de LaTeX. Lo tinico que se requiere hacer es usar el signo $ para
encapsular cualquier texto (leyenda, titulo, etiqueta, etc.). Por ejemplo “Sy=x"3S"
‘Aqui, sin embargo, podemos encontramos con un sutil problema con el cédigo LaTeX y las cadenas de
texto de Python. En LaTeX frecuentemente usamos el backslash \ en los comandos, por ejemplo \alpha
para producir el simbolo $\alpha$. Pero \ ya tiene un significado en las cadenas Python (el caracter de
escape). Para evitar que Python malinterprete nuestro cbdigo LaTeX necesitamos usar cadenas de textos
“crudas” ("raw"), Las cadenas de texto crudas son precedidas por’, por ejemplo r"\alpha" 0
r'\alpha’ enlugarde “\alpha" y '\alpha’
hitps:Inoviewer upyter.orglurls/d.dropbox.convslatSranéocZgakmSPytnon05_Matplotibipynb 917ar2020 -Jupyter Notebook Viewer
In [18]:
fig, ax = pl.subplots()
ax.plot(x, x**2, labe: \alphar2$")
ax.plot(x, x**3, labe \alphar3$")
ax.set_xlabel(r'$\alpha$", fontsize=18)
ax.set_ylabel(r'$y$", fontsize=18)
ax.set_title(u'Titulo')
ax.legend(loc=2); # esquina superior izquierda
Titulo
0
100
Podemos también cambiar el tamaio y él tipo de letra globalmente, de modo que se aplique a todos los
textos de una figura (etiquedas numéricas, etiquetas de ejes, titulos, leyendas, etc.)
In [19]:
#t Actualiza Los pardmetros de configuracién de MatpLotLib:
#matpLotlib
pl.rcParams.update({'font.size': 18, ‘font.family': ‘serif'})
hitps:Inoviewer upyter.orglurls/d.dropbox.convslatSranéocZgakmSPytnon05_Matplotibipynb 1083172020 -Jupyler Notebook Viewer
In [20]:
fig, ax = pl.subplots()
\alphar2$
\alphar3$")
ax.plot(x, x**2, labe:
ax.plot(x, x**3, labe
ax. set_xlabel(r'$\alpha$")
ax. set_ylabel(r'$y$")
ax.set_title(u'Titulo')
ax.legend(loc=2); # esquina superior izquierda
Titulo
125
a
100) ge
75
~
50
25
i}
0 1 2 3 4 5
a
In [21]:
# vuelve a La configuracién original
pl.rcParams.update({'font.size': 12, ‘font.family': ‘sans'})
Definiendo colores, anchos y tipos de linea
Colores
En Matplotlib podemos definir los colores de las lineas y otrs elementos gréficos de distintas maneras.
Primero, podemos usar la sintaxis tipo MATLAB donde ‘b' signifuca azul (blue) ‘g’ significa verde
(green), etc. La API MATLAB para para seleccionar tipos de linea también esta disponible: por ejemplo 'b.-
* significa linas con puntso azules.
hitps:Inoviewer upyter.orglurls/d.dropbox.convslatSranéocZgakmSPytnon05_Matplotibipynb m17ar2020 -Jupyter Notebook Viewer
In [22]:
fig, ax = pl.subplots()
# SeLeccidn de color y estilo de Linea tipo MATLAB
ax.plot(x, x*#2, 'b.-') # Linea con puntos azul
ax.plot(x, x**3, 'g--') # Linea a trazos verde
out[22]:
[]
120
100
8 8 8 8
En Matplotlib también podemos definir colores por su nombre o sus cédigos RGB, y opcionalmente
suministrar un valor alfa, usando los argumentos color y alpha
hitps:Inoviewer upyter.orglurls/d.dropbox.convslatSranéocZgakmSPytnon05_Matplotibipynb
12817ar2020 -Jupyter Notebook Viewer
In [23]:
fig, ax = pl.subplots()
ax.plot(x, x#1, color:
ax.plot(x, x2, color:
ax.plot(x, x#3, color="
"red", alpha=0.5) # rojo semi-transparente
# cédigo RGB para un color azuLado
# cédigo RGB para un color verdoso
out(23]:
[]
Estilos de linea y marcadores
Para cambiar el ancho de una linea podemos usar el argumento linewidth 0 Iw, yelestilo de linea
puede ser seleccioando usando los argumentos linestyle o 1s
hitps:Inoviewer upyter.orglurls/d.dropbox.convslatSranéocZgakmSPytnon05_Matplotibipynb
13317ar2020 -Jupyter Notebook Viewer
In [24]:
fig, ax = pl.subplots(figsize=(12,6))
Linewidth=0.25)
linewidth=0.5@)
linewidth=1.0@)
Linewidth=2.0@)
ax.plot(x, x+1, color
ax.plot(x, x12, color
ax.plot(x, x43, color
ax.plot(x, x4, color
# posibles opciones de Linestype: “4 ‘-’,
ax.plot(x, x+5, color="red", Iw=2, linestyle=
ax.plot(x, x16, color
ax.plot(x, x+7, color
“24, ‘steps?
# Linea a trazos personalizada
Line, = ax.plot(x, x+8, color: Iwe1.50)
line.set_dashes([5, 10, 15, 10]) # formato: Longitud de Linea, Longitud de espacio, ..
# posibles simbolos de marcadores:
ax.plot(x, xt 9, green", I
ax.plot(x, x+10, green", li
ax.plot(x, x+11, green”, 1
ax.plot(x, x#12, green", Ls
# Tamafo y color del marcador
ax.plot(x, x#13, purple”, 1
ax.plot(x, x+14,
ax.plot(x, x#15,
ax.plot(x, x#16,
markerfacecolor="yellow”, markeredgewidth=2, markeredgecolor=
markersize=2)
markersize=4)
markersize=8, markerfacecol
markersize-8,
blue");
1s
50
25
20
Controlando la apariencia de los ejes
La apariencia de los ejes es un aspecto importante de una figura que comiinmente se requiere modificar
para confeccionar un grafico con calidad de publicaciéns. Necesitamos ser capaces de controlar dénde
estén ubicados los ticks y las etiquetas, modificar el tamafio de letra y posiblemente las etiquetas usadas
en los ejes. En esta seccién veremos cémo controlar estas propiedades en una figura de matplotlib
Rango de los ejes
Iitpsnbvewer jupyer. oglu. drapbox comvslatnen6ocZgakmsIPyinon05,Metlotipynb 140317ar2020 -Jupyter Notebook Viewer
Lo primero que quisieramos configurar es el rango de los ejes. Podemos hacer esto usando los métodos
set_ylim y set_xlim en un objeto ejes, 0 axis('tight") para oblener automaticamente rangos de
ejes "apretados"
In [25]:
fig, axes = pl.subplots(1, 3, figsiz
12, 4))
axes[].plot(x, x**2, x, x**3)
axes[0].set_title(“rango de ejes por defecto")
axes[1].plot(x, x**2, x, x**3)
axes[1].axis('tight')
axes[1].set_title("ejes apretados")
axes[2].plot(x, x**2, x, x**3)
axes[2].set_ylim([@, 62])
axes[2].set_xlim([2, 5])
axes[2].set_title(“rango de ejes personalizado”
rango de ejes por defecto jes apretados go fango de ees personalizado
wo 20
50
100 00
% % a
fo 2»
“ “ 2»
2 2 Py
° °
°
0 2 a ° 2 a 2 3 a 5
Posicionamiento de ticks y etiquetas de ticks personalizadas
Podemos determinar explicitamente dénde queremos que aparezcan los ticks de los ejes usando
set_xticks y set_yticks , donde ambos métodos toman una lista de valores que determinan dénde
se localizarén los ticks sobre el eje, Podemos también usar las funciones set_xticklabels y
set_yticklabels para ingresar una lista de etiquetas personalizadas para cada tick’
hitps:Inoviewer upyter.orglurls/d.dropbox.convslatSranéocZgakmSPytnon05_Matplotibipynb 15131