A word cloud displays text data where word size represents frequency or importance. Words are arranged to fill available space, creating a visual summary of text content that highlights prominent terms and patterns. This visualization is ideal for quickly identifying the most common themes or keywords in a body of text.

""" anyplot.ai
wordcloud-basic: Basic Word Cloud
Library: pygal 3.1.0 | Python 3.13.13
Quality: 91/100 | Updated: 2026-05-06
"""
import os
import sys
import xml.etree.ElementTree as ET
# Avoid naming conflict with pygal.py script name
# Remove current directory from path temporarily
cwd = os.getcwd()
sys.path = [p for p in sys.path if p not in ("", ".", cwd)]
import cairosvg
import numpy as np
import pygal
from pygal.style import Style
# Theme tokens
THEME = os.getenv("ANYPLOT_THEME", "light")
PAGE_BG = "#FAF8F1" if THEME == "light" else "#1A1A17"
INK = "#1A1A17" if THEME == "light" else "#F0EFE8"
# Okabe-Ito palette (first series = #009E73)
IMPRINT = ("#009E73", "#C475FD", "#4467A3", "#BD8233", "#AE3030", "#2ABCCD", "#954477")
# Data: Tech industry buzzwords with frequencies
word_frequencies = {
"Python": 180,
"Data": 165,
"Machine": 150,
"Learning": 145,
"Analytics": 135,
"Cloud": 128,
"API": 120,
"DevOps": 110,
"Docker": 105,
"Security": 98,
"Database": 92,
"Kubernetes": 85,
"AI": 78,
"Automation": 70,
"Microservices": 62,
"Agile": 55,
"Testing": 48,
"Git": 42,
"Linux": 38,
"Scalability": 32,
"AWS": 28,
"React": 25,
"Azure": 22,
"Terraform": 20,
"GraphQL": 18,
"Pipeline": 16,
"Deploy": 15,
"Build": 14,
}
# Canvas dimensions
canvas_w = 4800
canvas_h = 2700
# Scale frequencies to font sizes for large canvas
min_freq = min(word_frequencies.values())
max_freq = max(word_frequencies.values())
min_size = 60
max_size = 280
# Sort by frequency (largest first for better placement)
sorted_words = sorted(word_frequencies.items(), key=lambda x: x[1], reverse=True)
# Build word positions using improved spiral algorithm
word_data = []
placed_boxes = []
for i, (word, freq) in enumerate(sorted_words):
# Scale frequency to font size
size = int(min_size + (freq - min_freq) / (max_freq - min_freq) * (max_size - min_size))
# Estimate dimensions
w = len(word) * size * 0.55
h = size * 1.2
# Improved spiral placement - centered with balanced distribution
cx, cy = canvas_w / 2, canvas_h / 2 + 50
angle = 0
radius = 0
x, y = cx, cy
box = (cx - w / 2, cy - h / 2, w, h)
for _ in range(50000):
# Elliptical spiral - stretched for 16:9 canvas
test_x = cx + radius * 2.8 * np.cos(angle) - w / 2
test_y = cy + radius * 1.8 * np.sin(angle) - h / 2
# Check bounds with margins for title and edges
if 100 < test_x < canvas_w - w - 100 and 200 < test_y < canvas_h - h - 100:
test_box = (test_x, test_y, w, h)
# Check for overlap with placed words
overlap = False
for pb in placed_boxes:
x1, y1, w1, h1 = test_box
x2, y2, w2, h2 = pb
padding = 50 # Increased padding to prevent clustering
if not (
x1 + w1 + padding < x2 or x2 + w2 + padding < x1 or y1 + h1 + padding < y2 or y2 + h2 + padding < y1
):
overlap = True
break
if not overlap:
x = test_x + w / 2
y = test_y + h / 2
box = test_box
break
angle += 0.06 # Slower angle progression for better spacing
radius += 3.5 # Moderate radius growth
placed_boxes.append(box)
word_data.append({"word": word, "x": x, "y": y, "size": size, "color": IMPRINT[i % len(IMPRINT)]})
# Create minimal pygal chart as canvas
custom_style = Style(background=PAGE_BG, plot_background=PAGE_BG)
chart = pygal.XY(
style=custom_style,
width=canvas_w,
height=canvas_h,
show_legend=False,
show_x_labels=False,
show_y_labels=False,
show_x_guides=False,
show_y_guides=False,
show_dots=False,
stroke=False,
margin=0,
)
# Add dummy data (required for chart to render)
chart.add("", [(0, 0)])
# Render SVG and manually inject word cloud elements
svg_string = chart.render(is_unicode=True)
root = ET.fromstring(svg_string)
# Add title
title = ET.SubElement(root, "text")
title.set("x", "2400")
title.set("y", "130")
title.set("font-size", "84")
title.set("font-weight", "bold")
title.set("fill", INK)
title.set("text-anchor", "middle")
title.set("font-family", "sans-serif")
title.text = "wordcloud-basic · pygal · anyplot.ai"
# Add word cloud text elements
for item in word_data:
text_elem = ET.SubElement(root, "text")
text_elem.set("x", str(int(item["x"])))
text_elem.set("y", str(int(item["y"])))
text_elem.set("font-size", str(item["size"]))
text_elem.set("font-weight", "bold")
text_elem.set("fill", item["color"])
text_elem.set("text-anchor", "middle")
text_elem.set("dominant-baseline", "middle")
text_elem.set("font-family", "sans-serif")
text_elem.text = item["word"]
# Write modified SVG
modified_svg = ET.tostring(root, encoding="unicode")
with open(f"plot-{THEME}.svg", "w") as f:
f.write(modified_svg)
# Render PNG using cairosvg
cairosvg.svg2png(bytestring=modified_svg.encode(), write_to=f"plot-{THEME}.png")
# Save as HTML for interactive viewing
with open(f"plot-{THEME}.html", "w") as f:
f.write(
f"""<!DOCTYPE html>
<html>
<head>
<title>wordcloud-basic · pygal · anyplot.ai</title>
<style>
body {{ margin: 0; display: flex; justify-content: center; align-items: center; min-height: 100vh; background: {PAGE_BG}; }}
svg {{ max-width: 100%; height: auto; }}
</style>
</head>
<body>
{modified_svg}
</body>
</html>"""
)
Part of Basic Word Cloud on anyplot.ai.