Capítulo 12 Matplotlib orientado a objetos.
Otra forma de manejar el módulo es mediante objetos.
La idea principal detrás de usar el método orientado a objetos es crear geomas y luego sólo llamar a los métodos o atributos del mismo. Permite un control más fino y estructurado, especialmente útil para lidiar con un lienzo que tiene múltiples “axes” ya que se pueden invocar métodos y atributos individualmente para cada una. También es especialmente útil para personalización avanzada o integración en aplicaciones.
Hay dos objetos: Figure y Axes. El segundo objeto esta inmerso dentro del primero. Puede haber varios Axes dentro de una Figure. En general, crea una instancia de axes.Axes para renderizar visualizaciones en una instancia de figure.Figure.
Aunque hay dos formas en inglés de escribir ejes (axis y axes). La primera forma es el singular y la segunda el plural. En el contexto de Matplotlib no significan lo mismo. No confunda Axes, el objeto, y piense que hace referencia sólo a los ejes del geoma.
Iniciemos con un lienzo vacío:
Ahora se añadirá un objeto axes a la figura
from matplotlib import pyplot as plt
# %matplotlib inline
fig = plt.figure()
ax = fig.add_axes([0,0,1,1])Obsérvese que se especificó la dimensión del nuevo Axes en el siguiente orden: [izquierda, abajo, ancho, alto]. Los valores son una proporción del ancho y alto de la Figura.
Se trabaja de forma similar a pyplot:
from matplotlib import pyplot as plt
# %matplotlib inline
fig = plt.figure()
ax = fig.add_axes([0,0,1,1])
y = [1, 4, 9, 16, 25,36,49, 64]
x1 = [1, 16, 30, 42,55, 68, 77,88]
x2 = [1,6,12,18,28, 40, 52, 65]
l1 = ax.plot(x1,y,'ys-') # línea solida con color amarillo y marcador cuadrado.
l2 = ax.plot(x2,y,'go--') # línea a rayas color verde con marcador circular
_ = ax.legend(labels = ('TV', 'Celular'), loc = 'lower right') # legenda ubicada en la parte inferior derecha
_ = ax.set_title("Efecto de los anuncios en las ventas")
_ = ax.set_xlabel('Medio')
_ = ax.set_ylabel('Ventas')
En general, se trata del mismo método que en plt, pero precedido de set_.
Para yuxtaponer múltiples geomas se utiliza el comando subplots donde se indica cuantas filas y cuántas columnas, a manera de grilla, desea crear. Sea una fila y dos columnas para generar una gráfica al lado de otra.
import matplotlib.pyplot as plt
from matplotlib.ticker import FuncFormatter
import numpy as np
np.random.seed(42)
# Datos (7 días, realistas)
x = np.arange(1, 8)
y_tor = np.random.uniform(17, 25, len(x))
y_ba = np.random.uniform( 8, 15, len(x))
def c_to_f(c): return c*9/5 + 32
def f_to_c(f): return (f-32)*5/9
# Rango común en °C para comparación lado a lado
ymin_c, ymax_c = 8, 25
fig, (ax_can, ax_ba) = plt.subplots(1, 2, figsize=(12, 5),
sharex=True, sharey=True, constrained_layout=True)
_ = fig.suptitle(r"Temperaturas en la 1$^{\mathrm{ra}}$ semana de julio")
_ = ax_can.plot(x, y_tor, color='darkred', marker='o', markersize=3, linewidth = 0.8)
_ = ax_can.set_title("Toronto")
_ = ax_can.set_xlabel("Día")
_ = ax_can.set_ylabel("Grados Centígrados")
_ = ax_can.set_ylim(ymin_c, ymax_c)
ax_can_r = ax_can.twinx()
_ = ax_can_r.set_ylabel("")
_ = ax_can_r.tick_params(axis='y', right=False, labelright=False, length=0)
ax_can_r.spines['right'].set_visible(False)
_ = ax_ba.plot(x, y_ba, color='darkred', marker='s', markersize=3, linewidth = 0.8)
_ = ax_ba.set_title("Buenos Aires")
_ = ax_ba.set_xlabel("Día")
_ = ax_ba.set_ylabel("")
_ = ax_ba.tick_params(axis='y', left=False, labelleft=False)
_ = ax_ba.set_ylim(ymin_c, ymax_c) # mismo rango compartido
# Eje derecho en °F alineado con el rango compartido (8–25 °C -> 46–77 °F)
ax_ba_r = ax_ba.secondary_yaxis('right', functions=(c_to_f, f_to_c))
_ = ax_ba_r.set_ylabel("Grados Fahrenheit")
Al añadir sharey=True como tercer parámetro del comando subplots, comparte el eje y y sólo lo presenta a la izquierda.
Obsérvese el uso de ax para hacer referencia al objeto axes. Se podría haber denominado de otra manera.
Para cambiar el aspecto del objeto Axes se utilizan los siguientes métodos, entre otros:
ax.set_xlabel(): Equivalente a plt.xlabel
ax.set_ylabel(): Equivalente a plt.ylabel
ax.set_xlim([limite-inferior, limite-superior]) : Establece los límites que se muestran en el eje x de ax.
ax.set_ylim([limite-inferior, limite-superior]) : Establece los límites que se muestran en el eje y de ax.
ax.set_xticks([]): Equivalente a plt.xticks().
ax.set_yticks([]) : Equivalente a plt.yticks().
ax.set_xscale(escala) : Establece la escala del eje x de ax, donde el parámetro escala puede ser ‘linear’ (lineal) o ‘log’ (logarítmica).
ax.set_yscale(escala) : Establece la escala del eje y de ax, donde el parámetro escala puede ser ‘linear’ (lineal) o ‘log’ (logarítmica).
Obsérvese que se especificó que compartieran el eje y mediante el parámetro ‘sharey’.
Pruebe a ejecutar el código sin compartir el eje y
Si la matriz de gráficos tiene dos dimensiones, se debe especificar cada subplot:
import matplotlib.pyplot as plt
fig, caja = plt.subplots(2,2)
import numpy as np
x = np.arange(1,10, step = 0.1)
_ = caja[0][0].plot(x,x*x)
_ = caja[0][0].set_title('square')
_ = caja[0][1].plot(x,np.sqrt(x))
_ = caja[0][1].set_title('square root')
_ = caja[1][0].plot(x,np.exp(x))
_ = caja[1][0].set_title('exp')
_ = caja[1][1].plot(x,np.log10(x))
_ = caja[1][1].set_title('log')
fig.subplots_adjust(hspace=0.5) # height space entre filas
fig.subplots_adjust(wspace=0.5) # width space entre columnas
Se pueden representar figuras a voluntad indicando las coordenadas:

El método fill_between rellena la figura.
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
_ = ax.fill_between([0, 0.5, 1, 0], [0, 1, 0, 0])
Un sencillo ejemplo de plt adicional:
from matplotlib import pyplot as plt
import numpy as np
fig, ax = plt.subplots(figsize=(4, 3))
x = np.arange(4, 21, 0.5)
y = x ** 2
_ = ax.stem(x, y, bottom=0, linefmt='m', markerfmt='om', basefmt='m')