Clase 9: Visualización
Para graficar datos y funciones vamos a usar la biblioteca Matplotlib. Vamos a empezar discutiendo algunas de las características más generales del trabajo con esta biblioteca y mostrar algún ejemplo relativamente sencillo. Matplotlib está dividido en tres partes o capas conceptualmente bien delimitadas:
Una parte es la que hace el trabajo más básico creando y administrando cada objeto que forma parte del gráfico (líneas, texto, figuras, etc) así como sus relaciones,
Una segunda parte que permite un uso simple de las funciones anteriores: una interfaz con el usuario. Un ejemplo es el submódulo pyplot.
Una tercera componente que se encarga de presentar la figura en el formato adecuado. Esto es lo que se llama el Backend y se encarga de mostrar la figura en los distintos sistemas de ventanas, o en formatos de archivos correspondientes. Algunos ejemplos de backend son: PS (copias PostScript®), SVG (Scalable Vector Graphics), Agg (salida PNG de muy buena calidad), Cairo (png, pdf, ps, svg), GTK (interactivo, permite integrar matplotlib con aplicaciones Gtk+, que usa GNOME), PDF, WxWidgets (interactivo), Qt (interactivo).
Nosotros vamos a concentrarnos principalmente en aprender a utilizar pyplot
Interactividad
Trabajo con ventanas emergentes
Podemos trabajar en forma interactiva con gráficos desde una terminal de
Ipython
import matplotlib.pyplot as plt # o equivalentemente:
# from matplotlib import pyplot as plt
plt.plot([0,1,4,9,16,25])
El comando (la función) plot()
crea el gráfico pero no lo muestra.
Lo hacemos explícitamente con el comando show()
plt.show()
Vemos que es muy simple graficar datos.
Algunas cosas a notar:
Se abre una ventana
Se bloquea la terminal (no podemos dar nuevos comandos)
Si pasamos el mouse sobre el gráfico nos muestra las coordenadas.
Además del gráfico hay una barra de herramientas: .. image:: figuras/matplotlib_toolbar.png
- De derecha
a izquierda tenemos:
Grabar: Este botón abre una ventana para guardar el gráfico en alguno de los formatos disponibles.
Configuración de subplots: Permite modificar el tamaño y posición de cada gráfico en la ventana.
Agrandar (zoom) a rectángulo:
Si elegimos una región mientras apretamos el botón izquierdo, esta será la nueva región visible ocupando toda la ventana.
Si elegimos una región mientras apretamos el botón derecho, pone toda la vista actual en esta región.
Desplazar y agrandar (Pan and zoom): Este botón cumple dos funciones diferentes:
Con el botón izquierdo desplaza la vista.
Con el botón derecho la vista se agrandará achicará en los ejes horizontal y vertical en una cantidad proporcional al movimiento.
Si se oprime las teclas
x
oy
las dos funciones quedan restringidas al eje correspondiente.Home, Back, Forward son botones que nos llevan a la vista original, una vista hacia atrás o hacia adelante respectivamente
Si ocurre, como en este caso, que proveemos sólo una lista de datos, la
función plot()
la interpreta como los valores correspondientes al
eje vertical (eje y), y toma el índice del dato para la variable
independiente (eje x). Si queremos dar valores explícitamente para el
eje x debemos pasarlos como primer argumento.
plt.plot([0,1,2,3,4,5],[0,1,4,9,16,25])
plt.show()
Como vemos, para que muestre la ventana debemos hacer un llamado
explícito a la función show()
. Esto es así porque muchas veces
queremos realizar más de una operación sobre un gráfico antes de
mostrarlo. Sin embargo, hay varias alternativas respecto a la
interactividad de matplotlib (e ipython) que permiten adecuarla a
nuestro flujo de trabajo. La manera más común en una terminal es
utilizando las función ion()
(interactive on) para hacerlo
interactivo y la función ioff()
para no interactivo.
plt.ion() # Prendemos el modo interactivo
plt.plot([0,1,2,3,4,5],[0,1,4,9,16,25])
En el modo interactivo no sólo plot()
tiene implícito el comando
show()
sino que podemos seguir ingresando comandos con el gráfico
abierto.
Trabajo sobre notebooks
Para trabajar en ipython notebooks suele ser conveniente realizar los gráficos dentro de la misma página donde realizamos los cálculos
import matplotlib.pyplot as plt
plt.plot([1,2,3,4,5,6],[0,1,4,9,16,25])
[<matplotlib.lines.Line2D at 0x7f87f0b61cd0>]
En la práctica vamos a usar siempre Matplotlib junto con Numpy.
import numpy as np
import matplotlib.pyplot as plt
Gráficos simples
El paquete Matplotlib permite visualizar datos guardados en un archivo con unas pocas líneas
fdatos = '../data/ej_oscil_aten_err.dat'
x, y, yexp = np.loadtxt(fdatos, unpack=True)
plt.plot(x, y)
[<matplotlib.lines.Line2D at 0x7f87f0bf8ed0>]
Como vemos, es la curva que graficamos la clase anterior.
Si miramos el archivo vamos a ver que tiene una columna más que
corresponde a los valores medidos. En consecuencia le asignamos esta
tercera columna a una variable adicional yexp
al leerlo.
# Graficamos las segunda y tercera columnas como función de la primera
plt.plot(x,yexp, x,y)
[<matplotlib.lines.Line2D at 0x7f87f0939190>,
<matplotlib.lines.Line2D at 0x7f87f09394d0>]
Formato de las curvas
En los gráficos anteriores usamos la función plot()
en sus formas
más simples.
plot(y)
plot(x,y)
plot(x1,y1, x2, y2)
dando a la función plot()
la información mínima necesaria para
graficar los datos. Usualmente queremos poder elegir cómo vamos a
graficar nuestros datos.
Líneas, símbolos y colores
La forma más simple de elegir el modo de graficación de la curva es a través de un tercer argumento. Este argumento, que aparece inmediatamente después de los datos (x e y), permite controlar el tipo de línea o símbolo utilizado en la graficación. En el caso de la línea sólida se puede especificar con un guión (‘-’) o simplemente no poner nada, ya que línea sólida es el símbolo por defecto. Las dos especificaciones anteriores son equivalentes. También se puede elegir el color, o el símbolo a utilizar con este argumento:
plot(x,y,'g-')
plot(x,y,'ro')
plot(x,y,'r-o')
Para obtener círculos usamos una especificación que corresponde a ‘o’. Además podemos poner en este argumento el color. En este caso elegimos graficar en color “rojo (r), con una línea (-) + círculos (o)”.
Con esta idea modificamos el gráfico anterior
plt.plot(x,y,'-', x,yexp, 'ro')
[<matplotlib.lines.Line2D at 0x7f87f096fb90>,
<matplotlib.lines.Line2D at 0x7f87f09ab110>]
Para graficar más de una curva, en este formato simple, podemos ponerlo
todo en la misma función plot()
en la forma
plot(x1, y1, [formato], x2, y2, [formato2])
pero muchas veces es más
legible separar los llamados a la función, una para cada curva.
plt.plot(x,y, '-')
plt.plot(x,yexp, 'or')
[<matplotlib.lines.Line2D at 0x7f87f0803150>]
Al separar los llamados a la función plot()
obtenemos un código más
claro, principalmente cuando agregamos opciones de formato.
Los siguientes caracteres pueden utilizarse para controlar el símbolo de graficación:
Símbolo |
Descripción |
---|---|
‘-’ |
solid line style |
‘–’ |
dashed line style |
‘-.’ |
dash-dot line style |
‘:’ |
dotted line style |
‘.’ |
point marker |
‘,’ |
pixel marker |
‘o’ |
circle marker |
‘v’ |
triangle down marker |
‘^’ |
triangle up marker |
‘<’ |
triangle left marker |
‘>’ |
triangle right marker |
‘1’ |
tri down marker |
‘2’ |
tri up marker |
‘3’ |
tri left marker |
‘4’ |
tri right marker |
‘s’ |
square marker |
‘p’ |
pentagon marker |
‘*’ |
star marker |
‘h’ |
hexagon1 marker |
‘H’ |
hexagon2 marker |
‘+’ |
plus marker |
‘x’ |
x marker |
‘D’ |
diamond marker |
‘d’ |
thin diamond marker |
‘|’ |
vline marker |
‘_’ |
hline marker |
Los colores también pueden elegirse usando los siguientes caracteres:
Letra |
Color |
---|---|
‘b’ |
blue |
‘g’ |
green |
‘r’ |
red |
‘c’ |
cyan |
‘m’ |
magenta |
‘y’ |
yellow |
‘k’ |
black |
‘w’ |
white |
Por ejemplo, utilizando:
plt.plot(x, y1, 'gs', x, y2, '-k^', x, y3, '--r' )
obtenemos: .. image:: figuras/simple_varios.png
La función plot()
acepta un número variable de argumentos. Veamos lo
que dice la documentación
Signature: plt.plot(*args, **kwargs)
Docstring:
Plot y versus x as lines and/or markers.
Call signatures::
plot([x], y, [fmt], data=None, **kwargs)
plot([x], y, [fmt], [x2], y2, [fmt2], ..., **kwargs)
En particular, podemos usar los argumentos keywords (pares nombre-valor) para cambiar el modo en que se grafican los datos. Algunos de los más comunes son:
Argumento |
Valor |
---|---|
linestyle |
{‘-’, ‘–’, ‘-.’, ‘:’, ’’, …} |
linewidth |
número real |
color |
un color |
marker |
{‘o’, ‘s’, ‘d’, ….} |
markersize |
número real |
markeredgecolor |
color |
markerfacecolor |
color |
markevery |
número entero |
plt.plot(x,y,linewidth=1)
plt.plot(x,yexp, 'o', color='red', markersize=2)
[<matplotlib.lines.Line2D at 0x7f87f087c250>]
plt.plot(x,y,linewidth=5)
plt.plot(x,yexp, 'o', color='green', markersize=8)
[<matplotlib.lines.Line2D at 0x7f87f08ad850>]
plt.plot(x,y,linewidth=5, linestyle='dashed')
plt.plot(x,yexp, 'o', color='red', markersize=8, markeredgecolor='black',markevery=6)
[<matplotlib.lines.Line2D at 0x7f87f076c250>]
Nombres de ejes y leyendas
Vamos ahora a agregar nombres a los ejes y a las curvas.
Para agregar nombres a las curvas, tenemos que agregar un label
, en
este caso en el mismo comando plot()
, y luego mostrarlo con
`legend()
plt.plot(x,y, '-b', label="teoría")
plt.plot(x,yexp, 'or', label="medición")
#plt.legend()
plt.legend(loc="lower right", title="Mis datos")
<matplotlib.legend.Legend at 0x7f87f08712d0>
Para agregar nombres a los ejes usamos xlabel
y ylabel
:
plt.plot(x,yexp, 'or', label="medición")
plt.plot(x,y, '-b', label="teoría")
plt.legend(loc="lower right", title="Mis datos")
plt.xlabel('Tiempo (micro-segundos)')
plt.ylabel("Voltaje (mV)");
Los títulos a la figura se pueden agregar con title
plt.plot(x,y, '-b', label="teoría")
plt.plot(x,yexp, 'or', label="medición")
plt.legend(loc="lower right", title="Mis datos")
plt.xlabel('Tiempo (micro-segundos)')
plt.ylabel("Voltaje (mV)")
plt.title("Medición de ayer")
plt.axvline(x=1, color='gray')
plt.axhline(color='gray')
<matplotlib.lines.Line2D at 0x7f87f051d690>
Acá además agregamos una línea vertical y una horizontal.
Ejercicios 09 (a)
Realizar un programa para visualizar la función
\[f(x,n,w) = x^n |\sin(w x)|\]El programa debe realizar el gráfico para \(w=10\), con cuatro curvas para \(n=1,2,3,4\), similar al que se muestra en la siguiente figura
Escalas y límites de graficación (vista)
Para cambiar los límites de graficación se puede usar las funciones
xlim
para el eje horizontal y ylim
para el vertical
plt.plot(x,y, '-b', label="teoría")
plt.plot(x,yexp, 'or', label="medición")
plt.legend(loc="lower right", title="Mis datos")
plt.xlabel('Tiempo (micro-segundos)')
plt.ylabel("Voltaje (mV)")
plt.title("Medición de ayer")
plt.axvline(x=1, color='gray')
plt.axhline(color='gray')
plt.xlim((0,2.5))
plt.ylim((-0.4, 0.32))
(-0.4, 0.32)
Para pasar a escala logarítmica usamos xscale
o yscale
plt.plot(x,y, '-b', label="teoría")
plt.plot(x,yexp, 'or', label="medición")
plt.legend(loc="best", title="Mis datos")
plt.xlabel('Tiempo (micro-segundos)')
plt.ylabel("Voltaje (mV)")
plt.title("Medición de ayer")
plt.axvline(x=1, color='gray')
plt.axhline(color='gray')
plt.xlim((1.e-1,3))
plt.xscale('log')
plt.ylim((-0.4, 0.32))
(-0.4, 0.32)
plt.plot(x,1+y, '-b', label="teoría")
plt.plot(x,1+yexp, 'or', label="medición")
plt.legend(loc="best", title="Mis datos")
plt.xlabel('Tiempo (micro-segundos)')
plt.ylabel("Voltaje (mV)")
plt.title("Medición de ayer")
plt.axvline(x=1, color='gray')
plt.axhline(color='gray')
plt.xlim((1.e-1,3))
plt.xscale('log')
plt.yscale('log')
plt.ylim((0.6, 1.4))
(0.6, 1.4)
Exportar las figuras
Para guardar las figuras en alguno de los formatos disponibles
utilizamos la función savefig()
.
foname = 'ej_plot_osc'
plt.plot(x,y, '-b', label=r"$\frac{\sin(x^2)}{[2 + \cos (x)]^2}$")
plt.plot(x,yexp, 'or', label="$\mathrm{Medición}$")
plt.legend(loc="best", title="Mis datos", fontsize='x-large')
plt.xlabel(r'Tiempo ($\mu$-segundos)', fontsize='x-large')
plt.ylabel("Voltaje (mV)", fontsize='x-large')
plt.title("Medición de ayer")
plt.axvline(x=1, color='gray')
plt.axhline(color='gray')
plt.xlim((0,3))
plt.ylim((-0.4, 0.32))
plt.grid()
#plt.grid(color='green', linestyle='dashed', linewidth=1)
plt.savefig(f'{foname}.png')
plt.savefig(f'{foname}.pdf')
%pwd
'/home/fiol/Clases/IntPython/clases-python/clases'
help(plt.grid)
Help on function grid in module matplotlib.pyplot: grid(visible=None, which='major', axis='both', **kwargs) Configure the grid lines. Parameters ---------- visible : bool or None, optional Whether to show the grid lines. If any kwargs are supplied, it is assumed you want the grid on and visible will be set to True. If visible is None and there are no kwargs, this toggles the visibility of the lines. which : {'major', 'minor', 'both'}, optional The grid lines to apply the changes on. axis : {'both', 'x', 'y'}, optional The axis to apply the changes on. **kwargs : ~matplotlib.lines.Line2D properties Define the line properties of the grid, e.g.:: grid(color='r', linestyle='-', linewidth=2) Valid keyword arguments are: Properties: agg_filter: a filter function, which takes a (m, n, 3) float array and a dpi value, and returns a (m, n, 3) array and two offsets from the bottom left corner of the image alpha: scalar or None animated: bool antialiased or aa: bool clip_box: .Bbox clip_on: bool clip_path: Patch or (Path, Transform) or None color or c: color dash_capstyle: .CapStyle or {'butt', 'projecting', 'round'} dash_joinstyle: .JoinStyle or {'miter', 'round', 'bevel'} dashes: sequence of floats (on/off ink in points) or (None, None) data: (2, N) array or two 1D arrays drawstyle or ds: {'default', 'steps', 'steps-pre', 'steps-mid', 'steps-post'}, default: 'default' figure: .Figure fillstyle: {'full', 'left', 'right', 'bottom', 'top', 'none'} gapcolor: color or None gid: str in_layout: bool label: object linestyle or ls: {'-', '--', '-.', ':', '', (offset, on-off-seq), ...} linewidth or lw: float marker: marker style string, ~.path.Path or ~.markers.MarkerStyle markeredgecolor or mec: color markeredgewidth or mew: float markerfacecolor or mfc: color markerfacecoloralt or mfcalt: color markersize or ms: float markevery: None or int or (int, int) or slice or list[int] or float or (float, float) or list[bool] mouseover: bool path_effects: .AbstractPathEffect picker: float or callable[[Artist, Event], tuple[bool, dict]] pickradius: unknown rasterized: bool sketch_params: (scale: float, length: float, randomness: float) snap: bool or None solid_capstyle: .CapStyle or {'butt', 'projecting', 'round'} solid_joinstyle: .JoinStyle or {'miter', 'round', 'bevel'} transform: unknown url: str visible: bool xdata: 1D array ydata: 1D array zorder: float Notes ----- The axis is drawn as a unit, so the effective zorder for drawing the grid is determined by the zorder of each axis, not by the zorder of the .Line2D objects comprising the grid. Therefore, to set grid zorder, use .set_axisbelow or, for more control, call the ~.Artist.set_zorder method of each axis.
Acá también hemos utilizado formato tipo LaTeX para parte del texto. Si
utilizamos una expresión encerrada entre los símbolos $
, matplotlib
interpreta que está escrito en (un subconjunto) de LaTeX.
Matplotlib tiene un procesador de símbolos interno para mostrar la notación en LaTeX que reconoce los elementos más comunes, o puede elegirse utilizar un procesador LaTeX externo.
Dos gráficos en la misma figura
Hay varias funciones que permiten poner más de un gráfico en la misma
figura. Veamos un ejemplo utilizando la función subplots()
# %load scripts/ejemplo_08_5.py
#! /usr/bin/ipython3
""" Script realizado durante la clase 9. Dos figuras """
from pathlib import Path
import numpy as np
import matplotlib.pyplot as plt
plt.ion()
fname = 'ej_oscil_aten_err'
# Levantamos los datos
pardir = Path("..")
datfile = pardir / f'data/{fname}.dat'
x1, y1, y2 = np.loadtxt(datfile, unpack=True)
# Vamos a graficar sólo algunos valores (uno de cada 5)
x = x1[3:-10:5]
y = y1[3:-10:5]
yexp = y2[3:-10:5]
# Ejemplo de barras de error que dependen del eje x
error = 0.05 + 0.3 * np.abs(y)
fig, (ax0, ax1) = plt.subplots(num='subplots', nrows=2, sharex=True)
ax0.errorbar(x, yexp, yerr=error, fmt='-o')
ax1.plot(x, 2 * (yexp - y) / (yexp + y), 'or', markersize=8)
# Límites de graficación y títulos
ax0.set_title('Datos con error variable')
ax1.set_title('Error relativo')
ax0.set_ylabel('Voltaje (mV)', fontsize='x-large')
ax1.set_xlabel(r'Tiempo ($\mu$-seg)', fontsize='x-large')
ax1.set_ylabel('Error relativo', fontsize='x-large')
ax1.set_xlim((0, 3))
# Guardamos el resultado
plt.savefig(f'{fname}.png', dpi=150)
# %load scripts/ejemplo_08_5.py
#! /usr/bin/ipython3
""" Script realizado durante la clase 9. Dos figuras """
from pathlib import Path
import numpy as np
import matplotlib.pyplot as plt
plt.ion()
fname = 'ej_oscil_aten_err'
# Levantamos los datos
pardir = Path("..")
datfile = pardir / f'data/{fname}.dat'
x1, y1, y2 = np.loadtxt(datfile, unpack=True)
# Vamos a graficar sólo algunos valores (uno de cada 5)
x = x1[3:-10:5]
y = y1[3:-10:5]
yexp = y2[3:-10:5]
# Ejemplo de barras de error que dependen del eje x
error = 0.05 + 0.3 * np.abs(y)
fig, (ax0, ax1) = plt.subplots(num='subplots', figsize=(10,4), nrows=1, ncols=2)
ax0.errorbar(x, yexp, yerr=error, fmt='-o')
ax1.plot(x, 2 * (yexp - y) / (yexp + y), 'or', markersize=8)
# Límites de graficación y títulos
ax0.set_title('Datos con error variable')
ax1.set_title('Error relativo')
ax0.set_ylabel('Voltaje (mV)', fontsize='x-large')
ax1.set_xlabel(r'Tiempo ($\mu$-seg)', fontsize='x-large')
ax1.set_ylabel('Error relativo', fontsize='x-large')
ax1.set_xlim((0, 3))
# Guardamos el resultado
plt.savefig(f'{fname}_B.png', dpi=150)
En este ejemplo utilizamos un enfoque diferente al utilizado
anteriormente. Matplotlib presenta también una interface orientada a
objetos. La función subplots()
devuelve un par fig, axis
que son
dos objetos utilizados para representar la figura y un eje. Los
métodos de estos objetos presentan funcionalidad similar a las funciones
del módulo pyplot
.
Ejercicios 09 (b)
Para la función definida a trozos:
\[\begin{split}f(x) = \begin{cases} f_{1}(x) = x^{2}/8 & - \pi < x \le \pi/2 \\ f_{2}(x) = -0.3 x & \pi/2 < x < \pi \\ f_{3}(x) = -(x - 2 \pi)^{2}/6 & \pi \le x \le 5 \pi/2 \\ f_{4}(x) = (x - 2 \pi)/5 & 5 \pi/2 < x \le 3 \pi \end{cases}\end{split}\]realizar la siguiente figura de la manera más fiel posible.
Pistas: Buscar información sobre
plt.text()
,plt.fill_between()
y sobreplt.xticks
yplt.yticks
.Rehacer la siguiente figura:
.
Personalizando el modo de visualización
Matplotlib da la posibilidad de modificar el estilo de la graficación en distintas “etapas”.
Archivo de configuración
Cuando uno carga el módulo busca un archivo de configuración llamado
matplotlibrc
Primero busca un archivo de configuración en el directorio de trabajo también lo lee. En cada caso sobreescribe las variables.
Si la variable
MATPLOTLIBRC
existe (para el usuario), busca el archivo$MATPLOTLIBRC/matplotlibrc
Luego lee un archivo de configuración global del usuario, que dependiendo del sistema operativo puede ser: * En Linux,
.config/matplotlib/matplotlibrc
(o en$XDG_CONFIG_HOME/matplotlib/matplotlibrc
si la variableXDG_CONFIG_HOME
existe) * En otras plataformas puede estar en algún lugar como:C:\Documents and Settings\USUARIO\.matplotlib
Finalmente lee el archivo global de la instalación,
INSTALL/matplotlib/mpl-data/matplotlibrc
, donde INSTALL se refiere al lugar de instalación
En cualquier caso, podemos obtener el directorio y archivo de configuración con las funciones:
import matplotlib
matplotlib.get_configdir()
'/home/fiol/.config/matplotlib'
matplotlib.matplotlib_fname()
'/usr/share/matplotlib/mpl-data/matplotlibrc'
!head -n 120 '/usr/share/matplotlib/mpl-data/matplotlibrc'
#### MATPLOTLIBRC FORMAT ## NOTE FOR END USERS: DO NOT EDIT THIS FILE! ## ## This is a sample Matplotlib configuration file - you can find a copy ## of it on your system in site-packages/matplotlib/mpl-data/matplotlibrc ## (relative to your Python installation location). ## DO NOT EDIT IT! ## ## If you wish to change your default style, copy this file to one of the ## following locations: ## Unix/Linux: ## $HOME/.config/matplotlib/matplotlibrc OR ## $XDG_CONFIG_HOME/matplotlib/matplotlibrc (if $XDG_CONFIG_HOME is set) ## Other platforms: ## $HOME/.matplotlib/matplotlibrc ## and edit that copy. ## ## See https://matplotlib.org/stable/tutorials/introductory/customizing.html#customizing-with-matplotlibrc-files ## for more details on the paths which are checked for the configuration file. ## ## Blank lines, or lines starting with a comment symbol, are ignored, as are ## trailing comments. Other lines must have the format: ## key: val # optional comment ## ## Formatting: Use PEP8-like style (as enforced in the rest of the codebase). ## All lines start with an additional '#', so that removing all leading '#'s ## yields a valid style file. ## ## Colors: for the color values below, you can either use ## - a Matplotlib color string, such as r, k, or b ## - an RGB tuple, such as (1.0, 0.5, 0.0) ## - a double-quoted hex string, such as "#ff00ff". ## The unquoted string ff00ff is also supported for backward ## compatibility, but is discouraged. ## - a scalar grayscale intensity such as 0.75 ## - a legal html color name, e.g., red, blue, darkslategray ## ## String values may optionally be enclosed in double quotes, which allows ## using the comment character # in the string. ## ## This file (and other style files) must be encoded as utf-8. ## ## Matplotlib configuration are currently divided into following parts: ## - BACKENDS ## - LINES ## - PATCHES ## - HATCHES ## - BOXPLOT ## - FONT ## - TEXT ## - LaTeX ## - AXES ## - DATES ## - TICKS ## - GRIDS ## - LEGEND ## - FIGURE ## - IMAGES ## - CONTOUR PLOTS ## - ERRORBAR PLOTS ## - HISTOGRAM PLOTS ## - SCATTER PLOTS ## - AGG RENDERING ## - PATHS ## - SAVING FIGURES ## - INTERACTIVE KEYMAPS ## - ANIMATION ##### CONFIGURATION BEGINS HERE ## *********************************************************************** ## * BACKENDS * ## *********************************************************************** ## The default backend. If you omit this parameter, the first working ## backend from the following list is used: ## MacOSX QtAgg Gtk4Agg Gtk3Agg TkAgg WxAgg Agg ## Other choices include: ## QtCairo GTK4Cairo GTK3Cairo TkCairo WxCairo Cairo ## Qt5Agg Qt5Cairo Wx # deprecated. ## PS PDF SVG Template ## You can also deploy your own backend outside of Matplotlib by referring to ## the module name (which must be in the PYTHONPATH) as 'module://my_backend'. ##backend: Agg ## The port to use for the web server in the WebAgg backend. #webagg.port: 8988 ## The address on which the WebAgg web server should be reachable #webagg.address: 127.0.0.1 ## If webagg.port is unavailable, a number of other random ports will ## be tried until one that is available is found. #webagg.port_retries: 50 ## When True, open the web browser to the plot that is shown #webagg.open_in_browser: True ## If you are running pyplot inside a GUI and your backend choice ## conflicts, we will automatically try to find a compatible one for ## you if backend_fallback is True #backend_fallback: True #interactive: False #figure.hooks: # list of dotted.module.name:dotted.callable.name #toolbar: toolbar2 # {None, toolbar2, toolmanager} #timezone: UTC # a pytz timezone string, e.g., US/Central or Europe/Paris ## *********************************************************************** ## * LINES * ## *********************************************************************** ## See https://matplotlib.org/stable/api/artist_api.html#module-matplotlib.lines ## for more information on line properties. #lines.linewidth: 1.5 # line width in points #lines.linestyle: - # solid line #lines.color: C0 # has no affect on plot(); see axes.prop_cycle #lines.marker: None # the default marker #lines.markerfacecolor: auto # the default marker face color
Hojas de estilo
Matplotlib ha incorporado en los últimos años un paquete que permite
cambiar estilos fácilmente utilizando los mismos nombres para los
parámetros que hay en el archivo de configuración matplotlibrc
.
Este paquete tiene pre-definidos unos pocos estilos, entre ellos varios que emulan otros paquetes o programas. Veamos un ejemplo:
import numpy as np
import matplotlib.pyplot as plt
fdatos = '../data/ej_oscil_aten_err.dat'
x, y, yexp = np.loadtxt(fdatos, unpack=True)
plt.plot(x,y, x, 0.9*y)
[<matplotlib.lines.Line2D at 0x7f54b06180d0>,
<matplotlib.lines.Line2D at 0x7f54b06187d0>]
with plt.style.context('ggplot'):
plt.plot(x,y, x,0.9*y)
with plt.style.context('grayscale'):
plt.plot(x,y,'--', x,0.9*y)
with plt.style.context('fivethirtyeight'):
plt.plot(x,y, x,0.9*y)
with plt.style.context('seaborn-dark'):
plt.plot(x,y, x,0.9*y)
Los estilos disponibles están guardados en la variable available
(una lista)
plt.style.available
['Solarize_Light2',
'_classic_test_patch',
'_mpl-gallery',
'_mpl-gallery-nogrid',
'bmh',
'classic',
'dark_background',
'darker',
'fast',
'fivethirtyeight',
'ggplot',
'grayscale',
'latex',
'paper',
'presentation',
'seaborn-v0_8',
'seaborn-v0_8-bright',
'seaborn-v0_8-colorblind',
'seaborn-v0_8-dark',
'seaborn-v0_8-dark-palette',
'seaborn-v0_8-darkgrid',
'seaborn-v0_8-deep',
'seaborn-v0_8-muted',
'seaborn-v0_8-notebook',
'seaborn-v0_8-paper',
'seaborn-v0_8-pastel',
'seaborn-v0_8-poster',
'seaborn-v0_8-talk',
'seaborn-v0_8-ticks',
'seaborn-v0_8-white',
'seaborn-v0_8-whitegrid',
'tableau-colorblind10']
Combinando estilos
Los estilos pueden combinarse. En este caso, debe pasarse una lista de strings con los nombres de los estilos a aplicar. Se aplican en forma secuencial. Si dos estilos definen diferentes valores para una variable, el posterior sobreescribe los valores previos.
with plt.style.context(['fivethirtyeight','grayscale']):
plt.plot(x,y, x,0.9*y)
with plt.style.context(['grayscale','fivethirtyeight']):
plt.plot(x,y, x,0.9*y)
Creación de estilos propios
Podemos crear estilos propios, modificando los defaults con una sintaxis similar a la del archivo de configuración. Por ejemplo creemos un archivo ‘estilo_test’ con algunos parámetros
#!echo "lines.linewidth : 5" > estilo_test
#!echo "xtick.labelsize: 24" >> estilo_test
#!cat estilo_test
plt.plot(x,y)
[<matplotlib.lines.Line2D at 0x7f54b0694450>]
%pwd
'/home/fiol/Clases/IntPython/clases-python/clases'
with plt.style.context('estilo_test'):
plt.plot(x,y)
with plt.style.context('darker'):
plt.plot(x,y,'C1')
with plt.style.context('presentation'):
plt.plot(x,y,'g')
Para encontrar el lugar donde guardar las hojas de estilo podemos utilizar las funciones de matplotib:
matplotlib.get_configdir()
'/home/fiol/.config/matplotlib'
!ls -1 /home/fiol/.config/matplotlib/stylelib/
darker.mplstyle
latex.mplstyle
paper.mplstyle
presentation.mplstyle
!cat /home/fiol/.config/matplotlib/stylelib/darker.mplstyle
# -- mode: conf -- font.size : 14 lines.color : white lines.linewidth : 2 # line width in points lines.markersize : 8 patch.edgecolor : white text.color : white axes.facecolor : black axes.edgecolor : white axes.labelcolor : white # Seaborn dark palette axes.prop_cycle: cycler('color', ['001C7F', '017517', '8C0900', '7600A1', 'B8860B', '006374']) xtick.color : white ytick.color : white grid.color : white figure.facecolor : black figure.edgecolor : black savefig.facecolor : black savefig.edgecolor : black
Modificación de parámetros dentro de programas
Podemos cambiar directamente los parámetros dentro de nuestros programas
modificando el diccionario matplotlib.rcParams
import matplotlib as mpl
mpl.rcParams
# Plot con valores default
plt.plot(x,y)
[<matplotlib.lines.Line2D at 0x7f54a8577590>]
# Modificamos el valor default de ancho de línea
mpl.rcParams['lines.linewidth'] = 7
plt.plot(x,y)
[<matplotlib.lines.Line2D at 0x7f54a85a8e90>]
# El nuevo valor default podemos sobreescribirlo para este plot particular
plt.plot(x,y, lw=3)
[<matplotlib.lines.Line2D at 0x7f54a845b890>]
# Sin embargo, el nuevo valor default no es modificado
plt.plot(x,y)
[<matplotlib.lines.Line2D at 0x7f54a84d09d0>]
Ejercicios 09 (c)
Notando que la curva en color negro corresponde a la suma de las dos curvas en rojo, rehacer la siguiente figura:
Crear una hoja de estilo que permita hacer gráficos adecuados para posters y presentaciones. Debe modificar los tamaños para hacerlos legibles a mayores distancias (sugerencia 16pt). El tamaño de la letra de los nombres de ejes y en las leyendas debe ser mayor también. Las líneas deben ser más gruesas (sugerencia: ~4), los símbolos de mayor tamaño (sugerencia ~10).