|
1 | | -""" pyplots.ai |
| 1 | +""" anyplot.ai |
2 | 2 | donut-basic: Basic Donut Chart |
3 | | -Library: matplotlib 3.10.8 | Python 3.13.11 |
4 | | -Quality: 92/100 | Created: 2025-12-23 |
| 3 | +Library: matplotlib 3.10.9 | Python 3.14.4 |
| 4 | +Quality: 86/100 | Updated: 2026-04-24 |
5 | 5 | """ |
6 | 6 |
|
| 7 | +import os |
| 8 | + |
7 | 9 | import matplotlib.pyplot as plt |
8 | 10 |
|
9 | 11 |
|
10 | | -# Data - Budget allocation by category |
11 | | -categories = ["Marketing", "Development", "Operations", "Sales", "Support"] |
12 | | -values = [25, 35, 15, 18, 7] |
13 | | -total = sum(values) |
| 12 | +# Theme tokens |
| 13 | +THEME = os.getenv("ANYPLOT_THEME", "light") |
| 14 | +PAGE_BG = "#FAF8F1" if THEME == "light" else "#1A1A17" |
| 15 | +INK = "#1A1A17" if THEME == "light" else "#F0EFE8" |
| 16 | +INK_SOFT = "#4A4A44" if THEME == "light" else "#B8B7B0" |
14 | 17 |
|
15 | | -# Colors - Python Blue as primary, then colorblind-safe palette |
16 | | -colors = ["#306998", "#FFD43B", "#5BA0D0", "#8FBC8F", "#DDA0DD"] |
| 18 | +# Okabe-Ito palette (first segment is always the brand green) |
| 19 | +OKABE_ITO = ["#009E73", "#D55E00", "#0072B2", "#CC79A7", "#E69F00"] |
17 | 20 |
|
18 | | -# Create plot (3600x3600 px - square for symmetric pie/donut) |
19 | | -fig, ax = plt.subplots(figsize=(12, 12)) |
| 21 | +# Data - Annual budget allocation by department (USD thousands) |
| 22 | +categories = ["Engineering", "Marketing", "Operations", "Sales", "Support"] |
| 23 | +values = [480, 210, 155, 125, 55] |
| 24 | +total = sum(values) |
| 25 | + |
| 26 | +# Plot (square canvas for circular shapes) |
| 27 | +fig, ax = plt.subplots(figsize=(12, 12), facecolor=PAGE_BG) |
| 28 | +ax.set_facecolor(PAGE_BG) |
20 | 29 |
|
21 | | -# Create donut chart with wedgeprops for ring width |
22 | 30 | wedges, texts, autotexts = ax.pie( |
23 | 31 | values, |
24 | 32 | labels=categories, |
25 | 33 | autopct="%1.1f%%", |
26 | 34 | startangle=90, |
27 | | - colors=colors, |
28 | | - wedgeprops={"width": 0.5, "edgecolor": "white", "linewidth": 2}, |
29 | | - pctdistance=0.75, |
30 | | - labeldistance=1.1, |
| 35 | + colors=OKABE_ITO, |
| 36 | + wedgeprops={"width": 0.42, "edgecolor": PAGE_BG, "linewidth": 3}, |
| 37 | + pctdistance=0.78, |
| 38 | + labeldistance=1.08, |
| 39 | + textprops={"fontsize": 20, "color": INK}, |
31 | 40 | ) |
32 | 41 |
|
33 | | -# Style labels and percentages for 3600x3600 px |
34 | | -for text in texts: |
35 | | - text.set_fontsize(20) |
| 42 | +# Percentage labels sit on the colored wedges — use a light off-white for contrast |
36 | 43 | for autotext in autotexts: |
37 | 44 | autotext.set_fontsize(16) |
38 | | - autotext.set_color("white") |
| 45 | + autotext.set_color("#F0EFE8") |
39 | 46 | autotext.set_fontweight("bold") |
40 | 47 |
|
41 | | -# Add center text with total |
42 | | -ax.text(0, 0, f"Total\n${total}K", ha="center", va="center", fontsize=32, fontweight="bold", color="#306998") |
| 48 | +# Category labels use theme ink |
| 49 | +for text in texts: |
| 50 | + text.set_color(INK) |
43 | 51 |
|
44 | | -# Ensure circular shape |
45 | | -ax.set_aspect("equal") |
| 52 | +# Center metric |
| 53 | +ax.text(0, 0.08, "Total budget", ha="center", va="center", fontsize=18, color=INK_SOFT) |
| 54 | +ax.text(0, -0.06, f"${total:,}K", ha="center", va="center", fontsize=40, fontweight="bold", color=INK) |
46 | 55 |
|
47 | | -ax.set_title("donut-basic · matplotlib · pyplots.ai", fontsize=24, pad=20) |
| 56 | +ax.set_aspect("equal") |
| 57 | +ax.set_title( |
| 58 | + "Budget by Department · donut-basic · matplotlib · anyplot.ai", fontsize=24, fontweight="medium", color=INK, pad=20 |
| 59 | +) |
48 | 60 |
|
49 | 61 | plt.tight_layout() |
50 | | -plt.savefig("plot.png", dpi=300, bbox_inches="tight") |
| 62 | +plt.savefig(f"plot-{THEME}.png", dpi=300, bbox_inches="tight", facecolor=PAGE_BG) |
0 commit comments