Clase 11-12: Introducción a los gráficos

En esta clase vamos introducir una librería para realizar visualizaciones. Para estas visualizaciones vamos a poder utilizar diferentes typescomo números, textos, listas o diccionarios.

Hoy vamos a revisar la librería matplotlib que abreviamos como plt.

Ejemplo de visualizaciones (no marearse con el código)

import numpy as np
import matplotlib.pyplot as plt

# Fixing random state for reproducibility
np.random.seed(19680801)


N = 50
x = np.random.rand(N)
y = np.random.rand(N)
colors = np.random.rand(N)
area = (30 * np.random.rand(N))**2  # 0 to 15 point radii

plt.scatter(x, y, s=area, c=colors, alpha=0.5)
plt.show()
Copy to clipboard
_images/Clase11_12_2_0.png
import numpy as np
import matplotlib.pyplot as plt


data = [[ 66386, 174296,  75131, 577908,  32015],
        [ 58230, 381139,  78045,  99308, 160454],
        [ 89135,  80552, 152558, 497981, 603535],
        [ 78415,  81858, 150656, 193263,  69638],
        [139361, 331509, 343164, 781380,  52269]]

columns = ('Freeze', 'Wind', 'Flood', 'Quake', 'Hail')
rows = ['%d year' % x for x in (100, 50, 20, 10, 5)]

values = np.arange(0, 2500, 500)
value_increment = 1000

# Get some pastel shades for the colors
colors = plt.cm.BuPu(np.linspace(0, 0.5, len(rows)))
n_rows = len(data)

index = np.arange(len(columns)) + 0.3
bar_width = 0.4

# Initialize the vertical-offset for the stacked bar chart.
y_offset = np.zeros(len(columns))

# Plot bars and create text labels for the table
cell_text = []
for row in range(n_rows):
    plt.bar(index, data[row], bar_width, bottom=y_offset, color=colors[row])
    y_offset = y_offset + data[row]
    cell_text.append(['%1.1f' % (x / 1000.0) for x in y_offset])
# Reverse colors and text labels to display the last value at the top.
colors = colors[::-1]
cell_text.reverse()

# Add a table at the bottom of the axes
the_table = plt.table(cellText=cell_text,
                      rowLabels=rows,
                      rowColours=colors,
                      colLabels=columns,
                      loc='bottom')

# Adjust layout to make room for the table:
plt.subplots_adjust(left=0.2, bottom=0.2)

plt.ylabel("Loss in ${0}'s".format(value_increment))
plt.yticks(values * value_increment, ['%d' % val for val in values])
plt.xticks([])
plt.title('Loss by Disaster')

plt.show()
Copy to clipboard
_images/Clase11_12_3_0.png
import numpy as np
import matplotlib.pyplot as plt

np.random.seed(19680801)

# example data
mu = 100  # mean of distribution
sigma = 15  # standard deviation of distribution
x = mu + sigma * np.random.randn(437)

num_bins = 50

fig, ax = plt.subplots()

# the histogram of the data
n, bins, patches = ax.hist(x, num_bins, density=True)

# add a 'best fit' line
y = ((1 / (np.sqrt(2 * np.pi) * sigma)) *
     np.exp(-0.5 * (1 / sigma * (bins - mu))**2))
ax.plot(bins, y, '--')
ax.set_xlabel('Smarts')
ax.set_ylabel('Probability density')
ax.set_title(r'Histogram of IQ: $\mu=100$, $\sigma=15$')

# Tweak spacing to prevent clipping of ylabel
fig.tight_layout()
plt.show()
Copy to clipboard
_images/Clase11_12_4_0.png
import matplotlib.pyplot as plt
import numpy as np

np.random.seed(19680801)
data = np.random.randn(2, 100)

fig, axs = plt.subplots(2, 2, figsize=(5, 5))
axs[0, 0].hist(data[0])
axs[1, 0].scatter(data[0], data[1])
axs[0, 1].plot(data[0], data[1])
axs[1, 1].hist2d(data[0], data[1])

plt.show()
Copy to clipboard
_images/Clase11_12_5_0.png

Introducción a los gráficos

import matplotlib.pyplot as plt
Copy to clipboard

Para hacer un gráfico vamos a usar la función plot y show para mostrar (es como el print() de los gráficos).

Utilizando la lista [1,2,3,4] podemos hacer una línea recta

¿Es de 45°?

y = [1,2,3,4]
plt.plot(y)
plt.show()
Copy to clipboard
_images/Clase11_12_10_0.png

Lo anterior es equivalente a graficar

y = [1,2,3,4]
x = [0, 1, 2, 3]
plt.plot(x, y)
plt.show()
Copy to clipboard
_images/Clase11_12_12_0.png

Entonces si queremos hacer una línea de 45°

plt.plot(x, x)
plt.show()
Copy to clipboard
_images/Clase11_12_14_0.png

Los gŕaficos funcionan como capas, si colocamos un código seguido del otro (sin el plt.show()) se agregan al mismo plot.

y = [1,2,3,4]
plt.plot(y) #No es de 45°
plt.plot(y, y) #Es de 45°
plt.show()
Copy to clipboard
_images/Clase11_12_16_0.png

Entonces si queremos graficar (x, y) donde x = [1, 2, …, 10], y=2x2+1.

import numpy as np #Importamos la librería numérica
x = np.linspace(1, 10, 10) #Creamos un vector numérico entre 1-10 con 10 elementos
y = 2*x**2 +1  #Creamos la ecuación

plt.plot(x, y) #Graficamos
plt.show()
Copy to clipboard
_images/Clase11_12_18_0.png

Otro gráfico y = log(x)

x = np.linspace(1, 100, 1000) #Creamos un vector entre 1-100 con 1000 elementos
y = np.log(x)  #Sacamos el logaritmo de cada valor de x

plt.plot(x, y) #Graficamos (x, y)
plt.show()
plt.show()
Copy to clipboard
_images/Clase11_12_20_0.png

¿Cómo agregamos títlo y nombres de ejes?

x = np.linspace(1, 100, 1000) #Valores de x
y = np.log(x)  #Valores de y

plt.plot(x, y)
plt.title("Gráfico Logaritmo") #título
plt.xlabel("x") #título eje x
plt.ylabel("y") #título eje y
plt.show()
Copy to clipboard
_images/Clase11_12_22_0.png

Para agregar una leyenda usamos plt.legend()

plt.plot(x, y)
plt.title("Gráfico Logaritmo") #título
plt.xlabel("x") #título eje x
plt.ylabel("y") #título eje y
plt.legend("A") #Leyenda
plt.show()
Copy to clipboard
_images/Clase11_12_24_0.png

Entonces podemos graficar varias situaciones a partir de las diferentes capas.

#Ponderadores
α1 = 0.1
α2 = 0.4
α3 = 1
α4 = 1.5

#Valores de x e y
x = np.linspace(1, 100, 1000)
y1 = np.log(x)*α1
y2 = np.log(x)*α2
y3 = np.log(x)*α3
y4 = np.log(x)*α4


plt.plot(x, y1, label="α1="+str(α1))
plt.plot(x, y2, label="α2="+str(α2))
plt.plot(x, y3, label="α3="+str(α3))
plt.plot(x, y4, label="α4="+str(α4))
plt.title("Gráfico Logaritmo") #título
plt.xlabel("x") #título eje x
plt.ylabel("y") #título eje y
plt.legend()
plt.show()
Copy to clipboard
_images/Clase11_12_26_0.png

Gráfico de barra: recordar que los gráficos funcionan como capas

import matplotlib.pyplot as plt

# Datos
Valor = [1, 12, 7, 20, 60]
barras = ('A', 'B', 'C', 'D', 'E')
y_pos = np.arange(len(barras))

# Creamos las barras
plt.bar(y_pos, Valor)

# Creamos los nombres en el eje
plt.xticks(y_pos, barras)

# Mostrar el gráfico
plt.show()
Copy to clipboard
_images/Clase11_12_28_0.png

Le podemos cambiar la intensidad del color

# Datos
Valor = [1, 12, 7, 20, 60]
barras = ('A', 'B', 'C', 'D', 'E')
y_pos = np.arange(len(barras))

# Creamos las barras
plt.bar(y_pos, Valor, alpha=0.5) #Con el parámetro alpha cambiamos la intensidad del color

# Creamos los nombres en el eje
plt.xticks(y_pos, barras)

# Mostrar el gráfico
plt.show()
Copy to clipboard
_images/Clase11_12_30_0.png

Podemos cambiar el color usando el argumento “color”.

Para ver las opciones de colores pueden revisar el siguiente link 3: https://matplotlib.org/stable/gallery/color/named_colors.html

# Datos
Valor = [1, 12, 7, 20, 60]
barras = ('A', 'B', 'C', 'D', 'E')
y_pos = np.arange(len(barras))

# Creamos las barras
plt.bar(y_pos, Valor, color='red', alpha=0.8) #con "color" modificamos el color

# Creamos los nombres en el eje
plt.xticks(y_pos, barras)

# Mostrar el gráfico
plt.show()
Copy to clipboard
_images/Clase11_12_32_0.png

Para modificar la orientación del gráfico usamos “plt.barh” en lugar de “plt.bar” y los nombres de eje ahora se ponen en “plt.yticks”.

# Datos
Valor = [1, 12, 7, 20, 60]
barras = ('A', 'B', 'C', 'D', 'E')
y_pos = np.arange(len(barras))

# Creamos las barras
plt.barh(y_pos, Valor, color='red', alpha=0.8) #con "color" modificamos el color

# Creamos los nombres en el eje
plt.yticks(y_pos, barras)

# Mostrar el gráfico
plt.show()
Copy to clipboard
_images/Clase11_12_34_0.png

Con estos ejemplos básicos, junto a un poco de información adicional podemos crear un gráfico de barras para dos grupos diferentes.

Para esto vamos a utilizar el argumento “width” que nos va a permitir separar las barras.

Para ver los otros argumentos de los “plot.bar” pueden ver el siguiente link 4: https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.bar.html

Valor1 = [1, 12, 7, 20, 60]
Valor2 = [10, 5, 12, 20, 40]

barras = ('A', 'B', 'C', 'D', 'E')
y_pos = np.arange(len(barras))
bar_width = 0.35
# Creamos las barras

'''barra 1''' #Podemos escribir los elementos del gráfico separados por coma y por saltos de línea
plt.bar(y_pos, Valor1, 
        bar_width, 
        color='red', 
        alpha=0.8, 
        label = "Caso 1") 

'''barra 2'''
plt.bar(y_pos+bar_width, Valor2, 
        bar_width, 
        color='green', 
        alpha=0.6, 
        label = "Caso 2") 

# Creamos los nombres en el eje
plt.xticks(y_pos+bar_width/2, barras)
plt.legend() #Para que nos muestre los labels
# Mostrar el gráfico
plt.show()
Copy to clipboard
_images/Clase11_12_36_0.png

Algunas preguntas para seguir utilizando gráficos:

  • ¿Podemos colocar un gráfico dentro de una función?

  • ¿Nos sirven los condicionales para un gráfico?

  • ¿Qué otros tipos de gráficos podemos crear?

  • ¿Nos sirven los loops para simplificar los códigos de un gráfico?

Actividad en clases

Usando el ejemplo de Mincer de la clase anterior, vamos a graficar los resultados.

Tenemos las funciones:

  • fun_edad_educ()

  • fun_exp()

  • mincer()

import random
import numpy as np
Copy to clipboard
def fun_edad_educ(n, eda_in, eda_end, edu_in, edu_end):
    edad_list = []
    educ_list = []    
    for i in range(n):
        edad = random.randint(eda_in, eda_end)
        educ = random.randint(edu_in, edu_end)
        while edad<educ:
            edad = random.randint(eda_in, eda_end)
            educ = random.randint(edu_in, edu_end)
            
        edad_list.append(edad)
        educ_list.append(educ)            
            
    return np.array(edad_list), np.array(educ_list)

def fun_exp(edad, educ):
    return edad-educ


def mincer(S, Exp):
    β0 = 9.7
    β1 = 0.14
    β2 = 0.07
    β3 = -0.001
    return β0 + β1*S + β2*Exp + β3*Exp**2
Copy to clipboard
#Obtener: edad y educación
edad, educ = fun_edad_educ(100, 15, 65, 0, 22)
#Obtener: experiencia
exp = fun_exp(edad, educ)
#Obtener: ln(y)
ln_y = mincer(educ, exp)
Copy to clipboard
  1. Crear un gráfico de puntos (scatter) entre edad y educación.

  2. Crear un gráfico de puntos entre experiencia (eje horizontal) y ln_y (eje vertical), donde los puntos sean rojos, agregar título de ejes, título de gráfico, y una línea punteada de 45°.

  3. Crear un gráfico de barras con el promedio, mediana, y desviación estándar de ln_y.

  4. Crear un histograma usando el ln_y.