Documentos de Académico
Documentos de Profesional
Documentos de Cultura
1 IEBS
1.1 Generación modular de gráficos con matplotlib en Python
Javier Cózar del Olmo
Índice
• Section ??
• Section ??
• Section ??
• Section ??
– Section ??
– Section ??
– Section ??
– Section ??
– Section ??
– Section ??
– Section ??
– Section ??
– Section ??
• Section ??
• Section ??
• Section ??
• Section ??
• Section ??
1
manera independiente, en aplicaciones tk o qt, en notebooks, en archivos de imagen, etc. Debido
a que el proceso de renderización depende del contexto, es necesario un backend específico para
cada uno de ellos. La siguiente línea muestra los backends disponibles.
Available matplotlib backends: ['tk', 'gtk', 'gtk3', 'wx', 'qt4', 'qt5', 'qt', 'osx', 'nbagg', '
En el caso de las libretas Jupyter, se trabaja con dos backends distintos: inline y notebook. El
primero de ellos muestra los gráficos como imágenes estáticas, y es usado frecuentemente cuando
las libretas se utilizan como informe (es el usado en los ejemplos anteriores). El segundo permite
cierto nivel de interactividad, es más flexible, y es más indicado cuando se han de hacer modifica-
ciones sobre un mismo gráfico de manera progresiva.
En Python, la elección del backend se hace mediante la función
matplotlib.use(nombre_backend). En Jupyter, la elección de un backend se puede hacer
mediante un magic.
1.2.2 Scripting
El módulo principal de esta capa es matplotlib.pyplot. Proporciona una interfaz, parecida a la
de otras herramientas como Matlab, que permite elaborar las gráficas directamente y, sobre todo
(por la dificultad que esto conlleva) gestionar la creación de figuras y el backend (documentación).
La siguiente celda importa este módulo, usualmente renombrado a plt.
Vamos a utilizar la interfaz de scripting de matplotlib. Eso significa que al ejecutar ciertas op-
eraciones construirá y enriquecerá el gráfico actual.
Un gráfico se crea ejecutando el comando plt.figure(), y a partir de ahí todos los comandos
hacen referencia a esa figura, hasta que se construya otra figura diferente.
La siguiente celda de código construye una gráfica sencilla y le asigna un título.
# Y creamos la figura
fig = plt.figure(figsize=(3,3))
plt.plot(x_data, y_data, scalex=True)
plt.title("Gráfica de ejemplo")
2
La llamada a estas funciones nos devuelven objetos de la figura o dentro de ella. Estos objetos
pueden ser usados a través de la API de Artist, o como argumentos por otras funciones.
Por ejemplo, si usamos el backend notebook, es necesario que cerremos la figura para que
deje de consumir recursos (y “terminar” esa interactividad). Existe una función expuesta en
matplotlib.pyplot para cerrar una figura abierta:
In [5]: plt.close(fig)
# cargamos mtcars
3
mtcars = pd.read_csv("https://vincentarelbundock.github.io/Rdatasets/csv/datasets/mtcars
# renombramos la primera columna a model
mtcars.rename({'Unnamed: 0': 'model'}, axis=1, inplace=True)
# creamos una nueva columna llamada brand (la marca del coche)
mtcars['brand'] = mtcars['model'].str.extract(r'(\w+)')
# y creamos las variables am y vs como categóricas
mtcars['am'] = pd.Categorical(mtcars['am']).rename_categories({0: 'automatic', 1: 'manua
mtcars['vs'] = pd.Categorical(mtcars['vs']).rename_categories({0: 'V-shaped', 1: 'straig
In [8]: mtcars.head()
Out[8]: model mpg cyl disp hp drat wt qsec vs \
0 Mazda RX4 21.0 6 160.0 110 3.90 2.620 16.46 V-shaped
1 Mazda RX4 Wag 21.0 6 160.0 110 3.90 2.875 17.02 V-shaped
2 Datsun 710 22.8 4 108.0 93 3.85 2.320 18.61 straight
3 Hornet 4 Drive 21.4 6 258.0 110 3.08 3.215 19.44 straight
4 Hornet Sportabout 18.7 8 360.0 175 3.15 3.440 17.02 V-shaped
fig = plt.figure(figsize=(10,5))
plt.plot(df_plot, ".b")
pass
4
In [15]: df_plot = mtcars.set_index("mpg")[["hp", "wt"]]
x = df_plot.index
y1 = df_plot.hp
y2 = df_plot.wt
fig = plt.figure(figsize=(10,5))
plt.plot(x, y1, ".b", x, y2, ".r")
pass
5
1.5 Tipos de gráficos
matplotlib.pyplot incluye una serie de funciones para generar gráficos, accesibles a través de
diferentes funciones. A continuación veremos las más utilizadas, así como los parámetros más
útiles.
1.5.1 plt.plot
Esta función genera un gráfico enfrentando los valores en el eje y contra los valores en el eje x.
Sirve para generar gráficas de líneas y de nubes de puntos.
In [16]: # necesitamos ordenar, ya que maplotlib está centrado en los valores y depende del orde
df = mtcars.sort_values("hp")
fig = plt.figure(figsize=(10,5))
plt.plot(df.hp, df.mpg)
pass
fmt = '[marker][line][color]'
donde marker se refiere al tipo de elemento que se usa para dibujar cada elemento (dato), line
si se dibuja una línea entre elementos, y color el color de los mismos. Todos ellos son opcionales.
1.6.1 Markers
6
character description
. 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
_ hline marker
character description
- solid line style
– dashed line style
-. dash-dot line style
: dotted line style
1.6.3 Colors
character color
b blue
g green
r red
c cyan
m magenta
y yellow
k black
w white
7
Además de la ventaja de codificar en un solo parámetro la forma del marcador, el tipo de línea y
el color, las funciones permiten pasar de forma posicional este argumento junto con los datos de
cada serie.
En la siguiente celda vamos a construir una gráfica plt.plot con dos series de datos. La
primera será una línea continua azul, y la segunda una línea discontinua roja en la que los datos
vienen marcados con x.
# Y creamos la figura
fig = plt.figure(figsize=(3,3))
plt.plot(x_data, y1_data, "-", x_data, y2_data, "x--r")
pass
También podemos, por ejemplo, dibujar los puntos de diferente color en función del valor de
una variable. Esto se consigue imprimiéndolos en diferentes series de valores.
8
Por el contrario, una de las desventajas es que no nos permite separar la definición de cada
uno de estos elementos por serie de datos, es decir, no permite dibujar una línea negra en la que
los marcadores sean puntos rojos.
En este caso, no queda más remedio que editar los argumentos del tipo de gráfico en concreto:
Line2D
9
1.6.4 stackplot
Los gráficos de pila permiten representar la relacion y suma de varias series. En Matplotlib se
construyen mediante la función pyplot.stackplot(). Si el eje X es una variable discreta, da la
misma información visual que los stacked bars. Si el eje X es una variable continua (por ejemplo,
una variable temporal) los stackplots son la opción adecuada.
In [39]: df = (
mtcars
.assign(n=1)
[['brand', 'am', 'n']]
.pivot_table(
values="n",
index='brand',
columns='am',
aggfunc="sum",
fill_value=0
)
)
fig = plt.figure(figsize=(10,5))
10
1.6.5 Bar
Son gráficos que se utilizan para mostrar como alguna cantidad varía entre un conjunto pequeño
de elementos (valores discretos). Se dibujan con la función pyplot.bar(). El primer argumento
debe ser una secuencia de labels (texto) o enteros, y el segundo un número indicando la altura de
cada barra.
Podemos editar el aspecto de las barras con los argumentos descritos en la documentación.
11
Si ponemos dos series, se imprimen en sucesión una detrás de otra.
12
Si lo que queremos es intercalarlas, tenemos que controlar la posición con el primer argumento.
Como debe ser un entero, debemos usar la función xticks (la describiremos más adelante) para
mostrar los textos.
df = (
mtcars
[["brand", "mpg", "am"]]
.pivot_table(values="mpg", index='brand', columns='am',aggfunc="mean", fill_value=0
)
barwidth = 0.4
indices = np.arange(len(df.index))
fig = plt.figure(figsize=(10,5))
13
Finalmente, existe una función idéntica llamada plt.barh que dibuja las columnas en horizon-
tal.
In [37]: df = (
mtcars
[["brand", "mpg", "am"]]
.pivot_table(values="mpg", index='brand', columns='am',aggfunc="mean", fill_value=0
)
barheight = 0.4
indices = np.arange(len(df.index))
fig = plt.figure(figsize=(10,7))
14
1.6.6 hist
La función pyplot.hist() construye un histograma a partir de un conjunto de datos con el
número de bins especificado. Este histograma puede representar en el eje y las frecuencias ab-
solutas, o las relativas. En este caso, con el parámetro density=True se indica que se utilicen las
frecuencias relativas.
plt.hist(
[mtcars.loc[lambda df: df.am == "manual"].mpg, mtcars.loc[lambda df: df.am == "auto
stacked=False, density=False, bins=10
)
pass
1.6.7 Boxplot
Se pueden crear con pyplot.boxplot. Representa la distribución de la. Es posible cambiar el
aspecto de las distintas componentes de las cajas, pero esto requiere acceder directamente a ellas.
Se pueden consultar diferentes parametros en la documentación.
plt.boxplot(
[mtcars.loc[lambda df: df.am == "manual"].mpg, mtcars.loc[lambda df: df.am == "auto
)
pass
15
1.6.8 Pie
Se construyen mediante la función pyplot.pie(). No son muy recomendados (se prefieren los
gráficos de barras) pero han sido ampliamente utilizados para comparar proporciones entre los
valores de una variable.
Se pueden consultar diferentes parámetros en la documentación. Permiten manejar multitud
de aspectos, como los colores (colors), el modo enque se muestra la información (autopct), si se
destaca algún sector y cuanto (explode), etc.
In [44]: df = mtcars.groupby("brand").mean()
fig = plt.figure(figsize=(10,10))
plt.pie(df.mpg, labels=df.index)
pass
16
1.6.9 Text
Se puede añador texto en una gráfica mediante pyplot.text(). Los dos primeros parámetros
constituyen el punto de referencia. Los parámetros horizontalalignment y verticalalignment
determinan cómo debe ser la alineación del texto con respecto a este punto.
plt.boxplot(
[mtcars.loc[lambda df: df.am == "manual"].mpg, mtcars.loc[lambda df: df.am == "auto
)
posx = 1
posy = mtcars.loc[lambda df: df.am == "manual"].mpg.mean()
17
plt.text(posx, posy, "Valor medio de mpg para manual", horizontalalignment="left")
pass
1.6.10 Annotate
Cuando se utilizan flechas y texto para hacer una anotación, se puede hacer directamente con la
función pyplot.annotate. Ésta toma como parámetros las coordenadas de la punta de la flecha y
el texto. En ambos casos, se puede especificar qué unidades se utilizan (en el ejemplo los datos).
También las propiedades de la flecha.
Se puede consultar la parametrización en la documentación.
plt.boxplot(
[mtcars.loc[lambda df: df.am == "manual"].mpg, mtcars.loc[lambda df: df.am == "auto
)
posx = 1
posy = mtcars.loc[lambda df: df.am == "manual"].mpg.mean()
plt.annotate(
"Valor medio de mpg para manual",
18
xy=(posx, posy),
xytext=(2, 30),
horizontalalignment="center",
textcoords = 'data',
arrowprops = dict(arrowstyle="->", color='b'), fontsize='small', color='b'
)
pass
plt.boxplot(
[mtcars.loc[lambda df: df.am == "manual"].mpg, mtcars.loc[lambda df: df.am == "auto
)
posx = 1
19
posy = mtcars.loc[lambda df: df.am == "manual"].mpg.mean()
plt.annotate(
"Valor medio de mpg para manual",
xy=(posx, posy),
xytext=(2, 30),
horizontalalignment="center",
textcoords = 'data',
arrowprops = dict(arrowstyle="->", color='b'), fontsize='small', color='b'
)
plt.hlines(posy, 0.5, 1.5, color="blue")
pass
20
In [211]: # Construimos los datos
x_data = [1,2,3,4,5,6,7,8,9,10]
y_data = [x ** 2 for x in x_data]
# Y creamos la figura
fig = plt.figure(figsize=(3,3))
plt.plot(x_data, y_data, ".-b")
# Añade el título
plt.title("Título de ejemplo", fontsize="large")
1.8 Ejes
Es posible establecer el rango de cada eje con las funciones pyplot.xlim() e pyplot.ylim(). Es
posible indicar los rangos de mayor a menor valor, cambiando así el aspecto de la gráfica.
También se pueden determinar los puntos concretos que se muestran en cada eje, su aspecto,
mediante pyplot.xticks() y pyplot.yticks().
Al igual que los títulos y las etiquetas, xticks y yticks aceptan argumentos de tipo Text.
# Y creamos la figura
21
fig = plt.figure(figsize=(6, 6))
plt.plot(x_data, y_data, ".-b")
22
1.9 Leyenda
En los gráficos, además, se pueden incluir leyendas. Esto se hace automáticamente añadiendo
una etiqueta a cada serie (argumento label="string"), y luego invocando pyplot.legend() con
los parámetros correspondientes. Uno de ellos, loc, determina dónde se coloca la leyenda. Si se
asigna el valor best la leyenda se coloca automáticamente, y puede cambiar de ubicación al añadir
o borrar elementos.
Información con respecto a leyendas puede encontrarse aquí. Para leyendas más complejas
puede consultarse esta guía.
for c in mtcars.am.cat.categories:
df = mtcars.loc[lambda df: df.am == c]
plt.plot(df.hp, df.mpg, 'o', label=c)
23
1.10 Estilos
Hasta el momento, todas las gráficas se han hecho con el aspecto por defecto. Sin embargo,
el método style de plt permite cambiar la aparencia de las gráficas, en muchos casos para
adaptarlas al contexto (presentación, artículo, notebook, etc. Existe una gran variedad de esti-
los disponibles, que pueden consultarse en el objeto pyplot.style.available.
Adicionalmente, existe un estilo llamado default que deja el estilo por defecto.
In [70]: plt.style.available
Out[70]: ['seaborn-dark',
'seaborn-darkgrid',
'seaborn-ticks',
'fivethirtyeight',
'seaborn-whitegrid',
'classic',
'_classic_test',
'fast',
'seaborn-talk',
'seaborn-dark-palette',
'seaborn-bright',
'seaborn-pastel',
'grayscale',
'seaborn-notebook',
'ggplot',
'seaborn-colorblind',
'seaborn-muted',
'seaborn',
'Solarize_Light2',
'seaborn-paper',
'bmh',
'tableau-colorblind10',
'seaborn-white',
'dark_background',
'seaborn-poster',
'seaborn-deep']
# Y creamos la figura
fig = plt.figure(figsize=(3,3))
plt.plot(x_data, y_data, ".-")
24
In [75]: # asi dejamos el estilo por defecto
plt.style.use('default')
25
# Y creamos la figura
fig, axes_grid = plt.subplots(2, 3, figsize=(10,3), sharey=False)
26