<jupyter_start><jupyter_text>📍 Data A basic [circle packing chart](https://www.python-graph-gallery.com/circular-packing) 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.<jupyter_code>import pandas as pd
df = pd.DataFrame({
    'Name': ['A', 'B', 'C', 'D', 'E', 'F'],
    'Value': [10, 2, 23, 87, 12, 65]
})<jupyter_output><empty_output><jupyter_text>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](https://www.python-graph-gallery.com/circular-packing) 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.<jupyter_code># 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)
)<jupyter_output><empty_output><jupyter_text>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<jupyter_code># 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))<jupyter_output><empty_output><jupyter_text>🎨 Visual tweaks Let's make something pretty and more insightful from this. Let's add a title, color the bubbles and add labels:<jupyter_code># 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
    ax.add_patch(plt.Circle((x, y), r, alpha=0.2, linewidth=2))
    plt.annotate(
          label, 
          (x,y ) ,
          va='center',
          ha='center'
     )<jupyter_output><empty_output><jupyter_text>>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).<jupyter_code># 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))<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11606746560142032, 'fraction_numerical': 0.011318242343541944, 'mean_word_length': 4.133257403189066, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 22, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '646831', 'license': '0BSD', 'n_tokens_mistral': 1517, 'n_tokens_neox': 1451, 'n_words': 540, 'path': 'src/notebooks/circular-packing-1-level-hierarchy.ipynb', 'repo_name': 's-lasch/The-Python-Graph-Gallery', 'size': '4506'}