You are on page 1of 31
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 31 7ar2020 -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 261 72020 -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 ast 7212020 -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 401 7ar2020 -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 5031 7212020 -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 31 7ar2020 -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 701 7ar2020 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 31 7ar2020 -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 91 7ar2020 -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 10831 72020 -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 m1 7ar2020 -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 1281 7ar2020 -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 1331 7ar2020 -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 14031 7ar2020 -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

You might also like