## 📍 Data

A basic circle packing chart based on 1 level of hierarchy only requires a 2 columns data frame. The first column provides the name of each item (used for labeling). The second column provides a numeric value for the item. It controls the bubble size.

``````import pandas as pd
df = pd.DataFrame({
'Name': ['A', 'B', 'C', 'D', 'E', 'F'],
'Value': [10, 2, 23, 87, 12, 65]
})``````

You can type `df.head(3)` to observe the 3 first rows of this dataset in case you're not sure how it looks like 🧐 .

## 🖥️ Circle Packing algorythm

In a basic circle packing chart with one level of hierarchy, each entity of the dataset is represented by a circle. The circle size is proportional to the item value it represents.

The hardest part of the job is to compute the position and size of each circle. Fortunately, the `circlify` library offers a `circlify()` function that does the computation. It requires as input:

• `data` : (necessary) A list of positive values sorted from largest to smallest
• `target_enclosure` : (optional) A target enclosure where the packed circles should fit (default to the unit circle (0, 0, 1))
• `show_enclosure` : (optional) A boolean indicating if the target enclosure should be appended to the output (default to False)

Let's compute circle positions for the dataset created above.

``````# import the circlify library
import circlify

# compute circle positions:
circles = circlify.circlify(
df['Value'].tolist(),
show_enclosure=False,
target_enclosure=circlify.Circle(x=0, y=0, r=1)
)``````

I strongly advise to use `print(circles)` to have a look to this newly created object. You will see that it provides `x`, `y` and `r` for each item of our dataset 🎉 .

## 📊 Basic chart

``````# import libraries
import circlify
import matplotlib.pyplot as plt

# Create just a figure and only one subplot
fig, ax = plt.subplots(figsize=(10,10))

# Remove axes
ax.axis('off')

# Find axis boundaries
lim = max(
max(
abs(circle.x) + circle.r,
abs(circle.y) + circle.r,
)
for circle in circles
)
plt.xlim(-lim, lim)
plt.ylim(-lim, lim)

# print circles
for circle in circles:
x, y, r = circle
ax.add_patch(plt.Circle((x, y), r, alpha=0.2, linewidth=2, fill=False))

`````` ## 🎨 Visual tweaks

Let's make something pretty and more insightful from this. Let's add a title, color the bubbles and add labels:

``````# import libraries
import circlify
import matplotlib.pyplot as plt

# Create just a figure and only one subplot
fig, ax = plt.subplots(figsize=(10,10))

# Title
ax.set_title('Basic circular packing')

# Remove axes
ax.axis('off')

# Find axis boundaries
lim = max(
max(
abs(circle.x) + circle.r,
abs(circle.y) + circle.r,
)
for circle in circles
)
plt.xlim(-lim, lim)
plt.ylim(-lim, lim)

# list of labels
labels = df['Name']

# print circles
for circle, label in zip(circles, labels):
x, y, r = circle
plt.annotate(
label,
(x,y ) ,
va='center',
ha='center'
)

`````` Note: the `circlize` library offers a `bubbles()` function that does all the drawing for you. But it does not provide a lot of customization, so I feel like `matplotlib` is a better option here.

## Space between bubbles

You can easily add spacing between bubbles. You just have to provide a percentage of the radius parameter of `add_patch()` (70% here).

``````# Create just a figure and only one subplot
fig, ax = plt.subplots(figsize=(10,10))

# Title
ax.set_title('Basic circular packing')

# Remove axes
ax.axis('off')

# Find axis boundaries
lim = max(
max(
abs(circle.x) + circle.r,
abs(circle.y) + circle.r,
)
for circle in circles
)
plt.xlim(-lim, lim)
plt.ylim(-lim, lim)

# list of labels
labels = df['Name']

# print circles
for circle, label in zip(circles, labels):
x, y, r = circle
ax.add_patch(plt.Circle((x, y), r*0.7, alpha=0.9, linewidth=2, facecolor="#69b2a3", edgecolor="black"))
plt.annotate(label, (x,y ) ,va='center', ha='center', bbox=dict(facecolor='white', edgecolor='black', boxstyle='round', pad=.5))

`````` ## Contact & Edit

👋 This document is a work by Yan Holtz. You can contribute on github, send me a feedback on twitter or subscribe to the newsletter to know when new examples are published! 🔥