Gráfico de barras apiladas en matplotlib

Gráficos de barras apiladas en Python

Los gráficos de barras apiladas representan los valores que toman ciertos grupos dentro de otros grupos. Por ejemplo, considera que personas que viven en cinco ciudades diferentes (esto es, los grupos 'G1', 'G2', 'G3', 'G4' y 'G5') respondieron Si o No a una pregunta y los resultados (el conteo de respuestas en cada ciudad) se guardaron en las variables valores1 y valores2.

Estos datos se pueden representar en Python con la función bar de matplotlib haciendo uso del argumento bottom, que representa los valores del eje Y en los que dibujar la parte inferior de las barras, lo que nos permite apilar unas barras sobre otras.

import matplotlib.pyplot as plt

# Datos
grupos = ['G1', 'G2', 'G3', 'G4', 'G5']
valores1 = [12, 19, 14, 27, 16]
valores2 = [21, 30, 15, 17, 20]

fig, ax = plt.subplots()

# Gráfico de barras apiladas
ax.bar(grupos, valores1)
ax.bar(grupos, valores2, bottom = valores1)

# plt.show()

Gráfico de barras apiladas en matplotlib

Gráfico de barras apiladas con tres subgrupos

Si tienes que apilar más de dos barras tendrás que pasar los valores agregados de los datos anteriores a bottom, como en el ejemplo siguiente.

import matplotlib.pyplot as plt
import numpy as np

# Datos
grupos = ['G1', 'G2', 'G3', 'G4', 'G5']
valores1 = [12, 19, 14, 27, 16]
valores2 = [21, 30, 15, 17, 20]
values3 = [15, 23, 12, 11, 15]

fig, ax = plt.subplots()

# Gráfico de barras apiladas
ax.bar(grupos, valores1)
ax.bar(grupos, valores2, bottom = valores1)
ax.bar(grupos, values3, bottom = np.add(valores1, valores2))

# plt.show()

Gráfico de barras apiladas en Python

Generalización para varios subgrupos

Sin embargo, si no quieres apilar los valores manualmente puedes unir los valores en un array de numpy y luego utilizar el siguiente bucle for:

import matplotlib.pyplot as plt
import numpy as np

# Datos
grupos = ['G1', 'G2', 'G3', 'G4', 'G5']

values = np.array([[12, 19, 14, 27, 16],
                  [21, 30, 15, 17, 20],
                  [15, 23, 12, 11, 15],
                  [2, 5, 1, 6, 8]])

fig, ax = plt.subplots()

# Gráfico de barras apiladas con un bucle
for i in range(values.shape[0]):
  ax.bar(grupos, values[i], bottom = np.sum(values[:i], axis = 0))

# plt.show()

Barras apiladas en Python y matplotlib

Grosor de las barras

El argumento width controla el grosor de las barras. El valor por defecto es 0.8.

import matplotlib.pyplot as plt

# Datos
grupos = ['G1', 'G2', 'G3', 'G4', 'G5']
valores1 = [12, 19, 14, 27, 16]
valores2 = [21, 30, 15, 17, 20]
grosor = 0.25

fig, ax = plt.subplots()

# Gráfico de barras apiladas
ax.bar(grupos, valores1, width = grosor)
ax.bar(grupos, valores2, width = grosor, bottom = valores1)

# plt.show()

Grosor de las barras de un gráfico de barras apiladas en Python

Barras de error

Puedes agregar barras de error a las barras apiladas con el argumento yerr. Tendrás que pasar la desviación típica para cada subgrupo. Ten en cuenta que puedes personalizar el color de las barras de error con ecolor y el tamaño de las barras horizontales con capsize.

import matplotlib.pyplot as plt

# Datos
grupos = ['G1', 'G2', 'G3', 'G4', 'G5']
valores1 = [12, 19, 14, 27, 16]
valores2 = [21, 30, 15, 17, 20]
valores1_std = [2, 1, 3, 0.5, 2]
valores2_std = [1, 4, 0.25, 0.75, 1]

fig, ax = plt.subplots()

# Gráfico de barras apiladas
ax.bar(grupos, valores1, yerr = valores1_std, ecolor = 'red')
ax.bar(grupos, valores2, yerr = valores2_std, ecolor = 'green', bottom = valores1)

# plt.show()

Gráfico de barras apiladas con barras de error en Python

Color de las barras

El color de las barras de cada subgrupo se puede personalizar con el argumento color. Ten en cuenta que también puedes modificar la transparencia de los colores con alpha.

Color de un gráfico de barras apiladas en matplotlib

import matplotlib.pyplot as plt

# Datos
grupos = ['G1', 'G2', 'G3', 'G4', 'G5']
valores1 = [12, 19, 14, 27, 16]
valores2 = [21, 30, 15, 17, 20]

fig, ax = plt.subplots()

# Gráfico de barras apiladas
ax.bar(grupos, valores1, color = "#024b7a", alpha = 0.5)
ax.bar(grupos, valores2, bottom = valores1, color = "#44a5c2", alpha = 0.5)

# plt.show()

Además, puedes modificar el color y grosor del borde de las barras con edgecolor y linewidth, respectivamente.

Color de borde de un gráfico de barras apiladas en matplotlib

import matplotlib.pyplot as plt

# Datos
grupos = ['G1', 'G2', 'G3', 'G4', 'G5']
valores1 = [12, 19, 14, 27, 16]
valores2 = [21, 30, 15, 17, 20]

fig, ax = plt.subplots()

# Gráfico de barras apiladas
ax.bar(grupos, valores1, color = "#44a5c2",
       edgecolor = "black", linewidth = 2)
ax.bar(grupos, valores2, bottom = valores1, color = "#ffae49",
       edgecolor = "black", linewidth = 2)

# plt.show()

Agregar una leyenda a los subgrupos

Puedes establecer una etiqueta para cada subgrupo con el argumento label. Una vez agregadas las etiquetas podrás llamar a la función legend para agregar una leyenda al gráfico, como en el ejemplo siguiente.

import matplotlib.pyplot as plt

# Datos
grupos = ['G1', 'G2', 'G3', 'G4', 'G5']
valores1 = [12, 19, 14, 27, 16]
valores2 = [21, 30, 15, 17, 20]

fig, ax = plt.subplots()

# Gráfico de barras apiladas
ax.bar(grupos, valores1, label = "Si")
ax.bar(grupos, valores2, bottom = valores1, label = "No")

ax.legend(loc = 'upper right')
ax.set_ylabel('Número de respuestas')

# plt.show()

Cómo agregar una leyenda a un gráfico de barras apiladas en Python

Gráfico de barras apiladas con etiquetas de valores

Puedes mostrar los valores numéricos para cada barra apilada con la función text de matplotlib. Para ello puedes utilizar un bucle for como el siguiente:

Gráfico de barras apiladas con etiquetas para cada grupo en Python

import matplotlib.pyplot as plt

# Datos
grupos = ['G1', 'G2', 'G3', 'G4', 'G5']
valores1 = [12, 19, 14, 27, 16]
valores2 = [21, 30, 15, 17, 20]

fig, ax = plt.subplots()

# Gráfico de barras apiladas
ax.bar(grupos, valores1, label = "Si")
ax.bar(grupos, valores2, bottom = valores1, label = "No")

# Etiquetas
for bar in ax.patches:
  ax.text(bar.get_x() + bar.get_width() / 2,
          bar.get_height() / 2 + bar.get_y(),
          round(bar.get_height()), ha = 'center',
          color = 'w', weight = 'bold', size = 10)

ax.legend(loc = 'upper right')
ax.set_ylabel('Número de respuestas')

# plt.show()

Valor total de cada grupo

Alternativamente, puedes agregar etiquetas con los valores del total para cada grupo o barra. Para ello, tendrás que sumar los valores de cada grupo y luego utilizar un bucle for que recorra cada valor.

Gráfico de barras apiladas con etiquetas con los valores totales en Python y matplotlib

import matplotlib.pyplot as plt
import numpy as np

# Datos
grupos = ['G1', 'G2', 'G3', 'G4', 'G5']
valores1 = [12, 19, 14, 27, 16]
valores2 = [21, 30, 15, 17, 20]

fig, ax = plt.subplots()

# Gráfico de barras apiladas
ax.bar(grupos, valores1, label = "Si")
ax.bar(grupos, valores2, bottom = valores1, label = "No")

# Suma de valores
total_values = np.add(valores1, valores2)

# Etiquetas con el total
for i, total in enumerate(total_values):
  ax.text(i, total + 0.5, round(total),
          ha = 'center', weight = 'bold', color = 'black')

ax.legend(loc = 'upper right')
ax.set_ylabel('Número de respuestas')

plt.show()
Better Data Visualizations

A Guide for Scholars, Researchers, and Wonks

Comprar en Amazon
Fundamentals of Data Visualization

A Primer on Making Informative and Compelling Figures

Comprar en Amazon

También te puede interesar