Diagrama de pila de Matplotlib - Tutorial y ejemplos

En este tutorial, veremos cómo trazar un diagrama de pila en Matplotlib. Cubriremos gráficos de pila simples y cómo importar y preprocesar un conjunto de datos, con ejemplos.

Introducción

Hay muchas bibliotecas de visualización de datos en Python, pero Matplotlib es la biblioteca más popular de todas. La popularidad de Matplotlib se debe a su confiabilidad y utilidad: es capaz de crear gráficos simples y complejos con poco código. También puede personalizar las tramas de varias formas.

En este tutorial, cubriremos cómo trazar diagramas de pila en Matplotlib.

Los gráficos de pila se utilizan para trazar datos lineales, en orden vertical, apilando cada gráfico lineal sobre otro. Por lo general, se utilizan para generar gráficos acumulativos.

Importación de datos

Usaremos un dataset de vacunas contra el Covid-19, de Nuestro mundo en datos, específicamente, el dataset que contiene las vacunas acumuladas por país.

Comenzaremos importando todas las bibliotecas que necesitamos. Importaremos Pandas para leer y analizar el conjunto de datos, Numpy para generar valores para el eje X y, por supuesto, necesitaremos importar el módulo PyPlot de Matplotlib:

1
2
3
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np

Echemos un vistazo al DataFrame que usaremos:

1
2
dataframe = pd.read_csv("cumulative-covid-vaccinations.csv")
print(dataframe.head(25))

Estamos interesados ​​en Entity y total_vaccinations. Si bien también podríamos usar la función “Fecha”, para obtener una mejor comprensión de cómo van las vacunas día a día, trataremos la primera entrada como Día 0 y la última entrada como * Día N*:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
     Entity Code        Date  total_vaccinations
0   Albania  ALB  2021-01-10                   0
1   Albania  ALB  2021-01-12                 128
2   Albania  ALB  2021-01-13                 188
3   Albania  ALB  2021-01-14                 266
4   Albania  ALB  2021-01-15                 308
5   Albania  ALB  2021-01-16                 369
...
16  Albania  ALB  2021-02-22                6728
17  Albania  ALB  2021-02-25               10135
18  Albania  ALB  2021-03-01               14295
19  Albania  ALB  2021-03-03               15793
20  Albania  ALB  2021-03-10               21613
21  Algeria  DZA  2021-01-29                   0
22  Algeria  DZA  2021-01-30                  30
23  Algeria  DZA  2021-02-19               75000
24  Andorra  AND  2021-01-25                 576

Este conjunto de datos requerirá un procesamiento previo, ya que este es un caso de uso específico. Sin embargo, antes de preprocesarlo, familiaricémonos con cómo se trazan generalmente los diagramas de pila.

Trace un diagrama de pila en Matplotlib

Stack Plots se utiliza para visualizar múltiples gráficos lineales, apilados uno encima del otro. Con un gráfico de líneas regular, trazaría la relación entre X e Y. Aquí, estamos trazando múltiples entidades Y en un eje X compartido, una encima de la otra:

1
2
3
4
5
6
7
8
9
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y1 = [5, 6, 4, 5, 7]
y2 = [1, 6, 4, 5, 6]
y3 = [1, 1, 2, 3, 2]

fig, ax = plt.subplots()
ax.stackplot(x, y1, y2, y3)
plt.show()

Esto resulta en:

simple stack plot

Dado que es un poco difícil de manejar con múltiples listas como esta, simplemente puede usar un diccionario, donde cada función yn es una entrada:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]

y_values = {
    "y1": [5, 6, 4, 5, 7],
    "y2": [1, 6, 4, 5, 6],
    "y3" : [1, 1, 2, 3, 2]
}

fig, ax = plt.subplots()
ax.stackplot(x, y_values.values())
plt.show()

Esto resulta en:

trazado de pila simple matplotlib

Dado que este tipo de gráfico puede hacer que te pierdas fácilmente en las pilas, es realmente útil agregar etiquetas adjuntas a los colores, configurando las claves () del diccionario y_values como el argumento labels, y agregando una leyenda a la trama:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]

y_values = {
    "y1": [5, 6, 4, 5, 7],
    "y2": [1, 6, 4, 5, 6],
    "y3" : [1, 1, 2, 3, 2]
}

fig, ax = plt.subplots()
ax.stackplot(x, y_values.values(), labels=y_values.keys())
ax.legend(loc='upper left')
plt.show()

Ahora, esto resulta en:

gráfico de pila de matplotlib con leyenda

Nota: La longitud de estas listas tiene que ser la misma. No puede trazar y1 con 3 valores e y2 con 5 valores.

Esto nos lleva a nuestro conjunto de datos de vacunación Covid-19. Preprocesaremos el conjunto de datos para que adopte la forma de un diccionario como este y trazaremos las vacunas acumulativas administradas a la población general.

Empecemos por agrupar el conjunto de datos por Entidad y total_vacunaciones, ya que cada Entidad actualmente tiene numerosas entradas. Además, querremos descartar las entidades denominadas Mundo y Unión Europea, ya que son entidades de conveniencia, agregadas para los casos en los que es posible que desee trazar una única línea acumulativa.

En nuestro caso, será efectivamente más del doble del recuento de total_vaccination, ya que incluyen valores ya trazados de cada país, como entidades individuales:

1
2
3
4
5
dataframe = pd.read_csv("cumulative-covid-vaccinations.csv")
indices = dataframe[(dataframe['Entity'] == 'World') | (dataframe['Entity'] == 'European Union')].index
dataframe.drop(indices, inplace=True)

countries_vaccinations = dataframe.groupby('Entity')['total_vaccinations'].apply(list)

Esto da como resultado una forma completamente diferente del conjunto de datos: en lugar de que cada entrada tenga su propia entrada Entidad/total_vaccinations, cada Entidad tendrá una lista de sus vacunas totales a lo largo de los días:

1
2
3
4
5
6
7
8
Entity
Albania           [0, 128, 188, 266, 308, 369, 405, 447, 483, 51...
Algeria                                              [0, 30, 75000]
Andorra           [576, 1036, 1291, 1622, 2141, 2390, 2526, 3611...
...
Croatia           [7864, 12285, 13798, 20603, 24985, 30000, 3455...
Cyprus            [3901, 6035, 10226, 17739, 25519, 32837, 44429...
Czechia           [1261, 3560, 7017, 10496, 11813, 12077, 13335,...

Ahora, conviertamos esta Serie en un diccionario y veamos cómo se ve:

1
2
cv_dict = countries_vaccinations.to_dict()
print(cv_dict)

Esto resulta en:

1
2
3
4
5
6
{
'Albania': [0, 128, 188, 266, 308, 369, 405, 447, 483, 519, 549, 550, 1127, 1701, 3049, 4177, 6728, 10135, 14295, 15793, 21613], 
'Algeria': [0, 30, 75000], 
'Andorra': [576, 1036, 1291, 1622, 2141, 2390, 2526, 3611, 4914],
...
}

Sin embargo, hay un problema aquí. No podemos trazar estas entradas si sus formas no son las mismas. Argelia tiene 3 entradas, mientras que Andorra tiene 9, por ejemplo. Para combatir esto, querremos encontrar la clave con la mayor cantidad de valores y cuántos valores hay.

Luego, construya un nuevo diccionario (no es recomendable modificar el diccionario original mientras lo recorre) e inserte 0s para cada día faltante en el pasado, ya que hubo 0 vacunas totales en esos días:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
max_key, max_value = max(cv_dict.items(), key = lambda x: len(set(x[1])))

cv_dict_full = {}
for k,v in cv_dict.items():
    if len(v) < len(max_value):
        trailing_zeros = [0]*(len(max_value)-len(v))
        cv_dict_full[k] = trailing_zeros+v
    else:
        cv_dict_full[k] = v
        
print(cv_dict_full)

Aquí, simplemente verificamos si la longitud de la lista en cada entrada es más corta que la longitud de la lista con la longitud máxima. Si es así, agregamos la diferencia entre ellos, en ceros, y agregamos ese valor a la lista original de valores.

Ahora, si imprimimos este nuevo diccionario, veremos algo como:

1
2
3
4
5
6
{
'Albania': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 188, 266, 308, 369, 405, 447, 483, 519, 549, 550, 1127, 1701, 3049, 4177, 6728, 10135, 14295, 15793, 21613],
'Algeria': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 75000],
'Andorra': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 576, 1036, 1291, 1622, 2141, 2390, 2526, 3611, 4914],
...
}

El país con más valores de entrada es:

1
print(max_key, len(max_value)) # Canada 90

Ahora que hemos preparado por completo nuestro conjunto de datos, y podemos trazarlo como lo hicimos antes con los Gráficos de pila, generemos los días y tracemos:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
dates = np.arange(0, len(max_value))

fig, ax = plt.subplots()
ax.stackplot(dates, cv_dict_full.values(), labels=cv_dict_full.keys())
ax.legend(loc='upper left', ncol=4)
ax.set_title('Cumulative Covid Vaccinations')
ax.set_xlabel('Day')
ax.set_ylabel('Number of people')

plt.show()

Dado que hay muchos países en el mundo, la leyenda estará bastante abarrotada, por lo que la hemos puesto en 4 columnas para que al menos encaje en la trama:

casos de covid de stackplot de matplotlib

Conclusión

En este tutorial, hemos repasado cómo trazar diagramas de pila simples, así como también cómo preprocesar conjuntos de datos y dar forma a los datos para que se ajusten a los diagramas de pila, usando los marcos Pandas y Matplotlib de Python.

Si está interesado en Visualización de datos y no sabe por dónde empezar, asegúrese de consultar nuestro paquete de libros en [Visualización de datos en Python](https://gum.co/data-visualization -en-paquete-de-libros-de-python):

Visualización de datos en Python Vuélvase peligroso con la visualización de datos ✅ Garantía de devolución de dinero de 30 días sin preguntas ✅ Principiante a Avanzado ✅ Actualizado periódicamente de forma gratuita (última actualización en abril de 2021) ✅ Actualizado con recursos y guías adicionales

Visualización de datos en Python con Matplotlib y Pandas es un libro diseñado para llevar a los principiantes absolutos a Pandas y Matplotlib, con conocimientos básicos de Python, y permitirles construir una base sólida para el trabajo avanzado con estas bibliotecas, desde gráficos simples. a gráficos 3D animados con botones interactivos.

Sirve como una guía detallada que le enseñará todo lo que necesita saber sobre Pandas y Matplotlib, incluido cómo construir tipos de gráficos que no están integrados en la propia biblioteca.

Visualización de datos en Python, un libro para desarrolladores principiantes e intermedios de Python, lo guía a través de la manipulación de datos simple con Pandas, cubre bibliotecas de trazado centrales como Matplotlib y Seaborn, y le muestra cómo aprovechar las bibliotecas declarativas y experimentales. como Altair. Más específicamente, a lo largo de 11 capítulos, este libro cubre 9 bibliotecas de Python: Pandas, Matplotlib, Seaborn, Bokeh, Altair, Plotly, GGPlot, GeoPandas y VisPy.

Sirve como una guía práctica única para la visualización de datos, en una plétora de herramientas que podría usar en su carrera.