Circular packing en Python con circlify

Librería

circlify

Autor principal

Elmotec

Un gráfico de circular packing representa cada grupo como un círculo cuya área es proporcional a su valor, y los círculos se agrupan sin solaparse. Cuando los datos son jerárquicos los círculos se anidan. La librería circlify calcula la posición y el tamaño de los círculos y matplotlib los dibuja. Los ejemplos muestran la población (en millones) por continente y país.

Circular packing con circlify

circlify.circlify recibe los valores y devuelve una lista de círculos con sus coordenadas y su radio. Dibuja cada uno con plt.Circle.

import circlify
import matplotlib.pyplot as plt

data = [{"id": "Asia", "datum": 4800}, {"id": "África", "datum": 1460},
        {"id": "Europa", "datum": 745}, {"id": "America", "datum": 1040},
        {"id": "Oceanía", "datum": 45}]

circles = circlify.circlify(data, show_enclosure = False)

fig, ax = plt.subplots()
ax.axis("off")
ax.set_xlim(-1, 1)
ax.set_ylim(-1, 1)
ax.set_aspect("equal")

for circle in circles:
    x, y, r = circle
    ax.add_patch(plt.Circle((x, y), r, alpha = 0.6, linewidth = 2, edgecolor = "white"))
# plt.show()

Gráfico de circular packing en Python

Etiquetas y colores

Cada círculo conserva los datos originales en circle.ex, por lo que puedes escribir el nombre de cada grupo en el centro de su círculo y usar un color diferente para cada uno.

import circlify
import matplotlib.pyplot as plt

data = [{"id": "Asia", "datum": 4800}, {"id": "África", "datum": 1460},
        {"id": "Europa", "datum": 745}, {"id": "America", "datum": 1040},
        {"id": "Oceanía", "datum": 45}]

circles = circlify.circlify(data, show_enclosure = False)
colors = plt.cm.Set2.colors

fig, ax = plt.subplots()
ax.axis("off")
ax.set_xlim(-1, 1)
ax.set_ylim(-1, 1)
ax.set_aspect("equal")

for circle, color in zip(circles, colors):
    x, y, r = circle
    ax.add_patch(plt.Circle((x, y), r, color = color))
    ax.annotate(circle.ex["id"], (x, y), ha = "center", va = "center")
# plt.show()

Gráfico de circular packing con etiquetas y colores en Python

Datos jerárquicos con círculos anidados

Agrega una clave children a cada grupo para crear una jerarquía. Los círculos que se devuelven tienen un atributo level que indica la profundidad, que puedes usar para dar un estilo diferente a cada nivel.

import circlify
import matplotlib.pyplot as plt

data = [{"id": "Europa", "datum": 280, "children": [
            {"id": "Alemania", "datum": 84}, {"id": "Francia", "datum": 68},
            {"id": "Italia", "datum": 59}, {"id": "España", "datum": 48}, {"id": "Polonia", "datum": 37}]},
        {"id": "Asia", "datum": 2950, "children": [
            {"id": "India", "datum": 1430}, {"id": "China", "datum": 1410},
            {"id": "Japón", "datum": 124}]},
        {"id": "America", "datum": 760, "children": [
            {"id": "EE. UU.", "datum": 335}, {"id": "Brasil", "datum": 216},
            {"id": "México", "datum": 129}, {"id": "Canadá", "datum": 39}]}]

circles = circlify.circlify(data, show_enclosure = False)

fig, ax = plt.subplots()
ax.axis("off")
ax.set_xlim(-1, 1)
ax.set_ylim(-1, 1)
ax.set_aspect("equal")

for circle in circles:
    x, y, r = circle
    if circle.level == 1:
        ax.add_patch(plt.Circle((x, y), r, color = "#A8DADC", alpha = 0.6))
        ax.annotate(circle.ex["id"], (x, y + r * 0.85), ha = "center", fontsize = 10, weight = "bold")
    else:
        ax.add_patch(plt.Circle((x, y), r, color = "#457B9D"))
        if r > 0.08:
            ax.annotate(circle.ex["id"], (x, y), ha = "center", va = "center", color = "white", fontsize = 8)
# plt.show()

Gráfico de circular packing anidado en Python

Consulta también cómo crear un treemap en matplotlib, que representa el mismo tipo de datos con rectángulos.

Storytelling con Datos

Visualización de datos para profesionales

Comprar en Amazon
Better Data Visualizations

A Guide for Scholars, Researchers, and Wonks

Comprar en Amazon

También te puede interesar