Gráficos#

Vamos manos a la obra. En las secciones anteriores vimos algunas de las precauciones que debemos tener en cuenta antes o durante la creación de visualizaciones. Ahora, vamos a hacer algunas. Para ello, nos vamos a apoyar en dos librerías de Python: matplotlib y plotly.

Vamos a aprovechar los datos que ya procesamos en la sección Bases para la visualización de datos

matplotlib#

matplotlib es una librería de Python que nos permite crear visualizaciones de datos. Es una de las librerías más populares para este propósito. En esta sección vamos a ver cómo crear algunos gráficos con esta librería.

Gráfico de barras#

Vamos a crear un gráfico de barras que nos permita comparar la cantidad de fallecidos diarios en México durante el primer semestre de 2022.

import matplotlib.pyplot as plt
# retomamos el dataframe que creamos en la sección anterior `muertes_diarias`
muertes_diarias['fecha_def'] = pd.to_datetime(muertes_diarias['fecha_def'])
# este paso **no es necesario**, pero nos servirá para hacer más legible las fechas
# básicamente, pasamos de un formato de fecha a una etiqueta de contenga el
# día, mes y año
muertes_diarias['fecha_def'] = muertes_diarias['fecha_def'].dt.strftime('%d/%m/%Y')

# creamos el gráfico
fig, ax = plt.subplots(figsize=(10, 6))
ax.bar(muertes_diarias['fecha_def'], muertes_diarias['fallecidos_diarios'])
ax.set_title('Fallecidos diarios en México (primer semestre 2022)')
ax.set_xlabel('Fecha')
ax.set_ylabel('Fallecidos')
# segmentamos las fechas para que no se solapen
ax.set_xticks(muertes_diarias.index[::30])

# mostramos el gráfico
plt.show()
../_images/S4P7-graficos_4_0.png

Vamos a explicar este código con más detalle:

  • Primero, importamos la librería matplotlib.pyplot y la renombramos como plt. Esta librería es la que nos permite crear visualizaciones con matplotlib.

import matplotlib.pyplot as plt
  • Luego, creamos el gráfico. Para ello, usamos la función plt.subplots. Esta función nos permite crear una figura y un eje. La figura es el lienzo donde se dibujará el gráfico. El eje es el objeto que nos permite manipular el gráfico. En este caso, creamos una figura de 10x6 pixeles.

fig, ax = plt.subplots(figsize=(10, 6))
../_images/S4P7-graficos_8_0.png
  • Luego, usamos el método bar del eje para crear el gráfico de barras. Este método recibe dos argumentos: el eje x y el eje y. En este caso, usamos la columna fecha_def como eje x y la columna fallecidos_diarios como eje y.

ax.bar(muertes_diarias['fecha_def'], muertes_diarias['fallecidos_diarios'])
<BarContainer object of 122 artists>
  • Luego, usamos los métodos set_title, set_xlabel y set_ylabel para agregar títulos y etiquetas a los ejes.

ax.set_title('Fallecidos diarios en México (primer semestre 2022)')
ax.set_xlabel('Fecha')
ax.set_ylabel('Fallecidos')
Text(3.200000000000003, 0.5, 'Fallecidos')
  • Finalmente, usamos el método set_xticks para segmentar las fechas en el eje x. Esto nos permite que las fechas no se solapen.

ax.set_xticks(muertes_diarias.index[::30])
[<matplotlib.axis.XTick at 0x7fc420eec9a0>,
 <matplotlib.axis.XTick at 0x7fc420eec970>,
 <matplotlib.axis.XTick at 0x7fc420594790>,
 <matplotlib.axis.XTick at 0x7fc420d600d0>,
 <matplotlib.axis.XTick at 0x7fc420f1f3d0>]
  • Por último, mostramos el gráfico con el método plt.show.

plt.show()

Gráfico de líneas#

Para hacer un gráfico de líneas es básicamente el mismo proceso del gráfico de barras, únicamente que utilizamos el método plot en lugar de bar.

# creamos el gráfico
fig, ax = plt.subplots(figsize=(10, 6))
ax.plot(muertes_diarias['fecha_def'], muertes_diarias['fallecidos_diarios']) # <-- aquí cambiamos `bar` por `plot`
ax.set_title('Fallecidos diarios en México (primer semestre 2022)')
ax.set_xlabel('Fecha')
ax.set_ylabel('Fallecidos')
# segmentamos las fechas para que no se solapen
ax.set_xticks(muertes_diarias.index[::30])

# mostramos el gráfico
plt.show()
../_images/S4P7-graficos_18_0.png

Y, como mostramos en la sección sobre el mensaje en la visualización de datos, podemos suavizar las líneas para que se vean más agradables. En este caso, usamos la media móvil simple de 7 días.

# encontrando la media hacemos el suavizado
muertes_diarias['fallecidos_diarios_smooth'] = muertes_diarias['fallecidos_diarios'].rolling(7).mean()
muertes_diarias[7:].head()
fecha_def fallecidos_diarios fallecidos_diarios_smooth
7 10/01/2022 4 2.857143
8 11/01/2022 3 3.142857
9 12/01/2022 4 3.428571
10 13/01/2022 9 4.285714
11 14/01/2022 11 4.857143
# creamos el gráfico
fig, ax = plt.subplots(figsize=(10, 6))
ax.plot(muertes_diarias['fecha_def'], muertes_diarias['fallecidos_diarios_smooth']) # <-- aquí cambiamos `bar` por `plot`
ax.set_title('Fallecidos diarios en México (primer semestre 2022)')
ax.set_xlabel('Fecha')
ax.set_ylabel('Fallecidos')
# segmentamos las fechas para que no se solapen
ax.set_xticks(muertes_diarias.index[::30])

# mostramos el gráfico
plt.show()
../_images/S4P7-graficos_21_0.png

Gráfico de dispersión#

Para hacer un gráfico de dispersión es básicamente el mismo proceso del gráfico de barras, únicamente que utilizamos el método scatter en lugar de bar.

No obstante, este método no es útil para utilizarlo con los datos que usamos en los ejemplos previos. En este caso, necesitamos hallar dos variables que podamos correlacionar, así sea débilmente. En este caso, veremos si existe alguna correlación entre el sexo y la edad de las personas que se contagiaron.

casos_edad_sexo = datos_covid.groupby(['edad', 'sexo']).size().reset_index(name='count')
casos_edad_sexo.corr()
edad count
edad 1.000000 -0.572095
count -0.572095 1.000000

Anticipamos que es una correlación lineal débil 1. Ahora, veámosla en un gráfico de dispersión.

# creamos el gráfico
fig, ax = plt.subplots(figsize=(10, 6))

# color de los puntos por cateogoría 'sexo'
colors = {'HOMBRE': 'red', 'MUJER': 'blue'}

ax.scatter(casos_edad_sexo['edad'], casos_edad_sexo['count'], c=casos_edad_sexo['sexo'].apply(lambda x: colors[x])) 
ax.set_title('Casos confirmados por edad y sexo')
ax.set_xlabel('Edad')
ax.set_ylabel('Casos confirmados')

# mostramos el gráfico
plt.show()
../_images/S4P7-graficos_25_0.png

Notarás que los contagios para mujeres y hombres son muy similares, por lo que comparten la misma tendencia. Es claro que no hay una correlación ya que entre mayor o menor edad no aumenta o disminuye el número de contagios. Lo que sí se observa es una tendencia, tanto en hombre o mujeres, de sufrir contagios principalmente entre los 20 y los 50 años. ¿Sucede lo mismo con los fallecimientos? Es lógico considerar que debe existir una fuerte correlación entre la edad y el número de fallecimientos, pero veamoslo.

# seleccionamos los casos en los que hubo fallecimientos
casos_edad_sexo_muertes = datos_covid.loc[datos_covid['fecha_def'].notnull(), ['edad', 'sexo', 'fecha_def']]

# agrupamos por edad y sexo
casos_edad_sexo_muertes = casos_edad_sexo_muertes.groupby(['edad', 'sexo']).size().reset_index(name='count')

# creamos el gráfico
fig, ax = plt.subplots(figsize=(10, 6))

# color de los puntos por cateogoría 'sexo'
colors = {'HOMBRE': 'red', 'MUJER': 'blue'}

ax.scatter(casos_edad_sexo_muertes['edad'], casos_edad_sexo_muertes['count'], c=casos_edad_sexo_muertes['sexo'].apply(lambda x: colors[x]))
ax.set_title('Fallecimientos por edad y sexo')
ax.set_xlabel('Edad')
ax.set_ylabel('Fallecimientos')

# mostramos el gráfico
plt.show()
../_images/S4P7-graficos_27_0.png

Notas que el gráfico es más disperso y que es más complicado cer una tendencia. Esto se debe en parte a que los contagios son mucho mayores que las defunciones, lo que hacer que la dispersión sea mayor. Por otra parte, con los datos que tenemos, es posible encontrar una correlación lineal positiva aunque débil entre la edad y el número de fallecimientos.

casos_edad_sexo_muertes.corr()
edad count
edad 1.000000 0.400549
count 0.400549 1.000000

Como vemos en la gráfica, hay una ligera tendencia a que entre mayor sea la edad, mayor sean los fallecimientos.

Pero, ¿qué pasa con otros padecimientos? ¿existe alguna relación entre la edad, la enfermedad y el número de fallecimientos? Afortunadamente no hemos eliminado ni modificado nuestro archivo original, así que podemos regresar a él y hacer un análisis similar.

lista_enfermedades = ['diabetes', 'epoc', 'asma', 'inmusupr', 'hipertension',  'cardiovascular', 'obesidad', 'renal_cronica', 'tabaquismo']

for l in lista_enfermedades:
    casos_edad_sexo_muertes = covid_nacional.loc[covid_nacional['fecha_def'].notnull(), ['edad', l, 'fecha_def']]
    casos_edad_sexo_muertes = casos_edad_sexo_muertes.groupby(['edad', l]).size().reset_index(name='count')
    correla = casos_edad_sexo_muertes.loc[casos_edad_sexo_muertes[l] == 'SI'].corr()
    print(l, correla)
diabetes            edad     count
edad   1.000000  0.306907
count  0.306907  1.000000
epoc            edad     count
edad   1.000000  0.364565
count  0.364565  1.000000
asma            edad     count
edad   1.000000  0.195403
count  0.195403  1.000000
inmusupr            edad     count
edad   1.000000  0.323069
count  0.323069  1.000000
hipertension            edad     count
edad   1.000000  0.423814
count  0.423814  1.000000
cardiovascular            edad     count
edad   1.000000  0.438819
count  0.438819  1.000000
obesidad            edad     count
edad   1.000000  0.255072
count  0.255072  1.000000
renal_cronica            edad     count
edad   1.000000  0.379559
count  0.379559  1.000000
tabaquismo            edad     count
edad   1.000000  0.403027
count  0.403027  1.000000

Como verás, las correlaciones lineales en todos los casos son muy débiles. Podemos graficar una de las tendencias más claras, la relacionada con la enfermedad cardiovascular y observar el gráfico:

casos_edad_sexo_muertes = covid_nacional.loc[covid_nacional['fecha_def'].notnull(), ['edad', 'cardiovascular', 'fecha_def']]
casos_edad_sexo_muertes = casos_edad_sexo_muertes.groupby(['edad', 'cardiovascular']).size().reset_index(name='count')

fig, ax = plt.subplots(figsize=(10, 6))

colors = {'SI': 'red', 'NO': 'blue', 'SE IGNORA': 'green'}

ax.scatter(casos_edad_sexo_muertes['edad'], casos_edad_sexo_muertes['count'], c=casos_edad_sexo_muertes['cardiovascular'].apply(lambda x: colors[x]))
ax.set_title('Fallecimientos por edad y enfermedad cardiovascular')
ax.set_xlabel('Edad')
ax.set_ylabel('Fallecimientos')

plt.show()
../_images/S4P7-graficos_34_0.png

¡Fantástico! Hemos experimentado con varios tipos de gráficas, intentando encontrar patrones en nuestros datos. Hallamos algunas tendencias, como que durante el segundo semetre de 2020 hubo un pico de mortalidad en el mes de febrero, aunque sin alcanzar a superar los 3o fallecimientos diarios. Por otra parte, los contagios se centraron en las poblaciones con edades entre 20 y 40 años, mientras que los fallecimientos se concentraron en las personas mayores de 60 años. Por último, no encontramos una relación entre las enfermedades y el número de fallecimientos.

Obviamente todavía podríamos realizar otras operaciones y gráficos, pero pasemos al siguiente tema, donde realizaremos las mismas gráficas pero con la ayuda de la librería Plotly, lo que dará un poco más de dinamismo a nuestras visualizaciones.

Notas#


1

En aras de la brevedad, en esta sección trataremos correlaciones lineales basados en el coeficiente de correlación de Pearson. Si quisiéramos profundizar más en la distribución de los datos, tendríamos que utilizar otro tipo de coeficientes no-lineales, como el coeficiente de correlación de Spearman o el coeficiente de correlación de Kendall. Si quieres realizar estos análisis con tus datos con Python, puedes explotar la librearía scipy.stats.