{"spec_id":"sunburst-basic","library":"matplotlib","language":"python","code":"\"\"\" anyplot.ai\nsunburst-basic: Basic Sunburst Chart\nLibrary: matplotlib 3.11.1 | Python 3.13.14\nQuality: 94/100 | Updated: 2026-07-26\n\"\"\"\n\nimport os\n\nimport matplotlib.patheffects as pe\nimport matplotlib.pyplot as plt\nimport numpy as np\n\n\n# Theme-adaptive chrome tokens (Imprint)\nTHEME = os.getenv(\"ANYPLOT_THEME\", \"light\")\nPAGE_BG = \"#FAF8F1\" if THEME == \"light\" else \"#1A1A17\"\nELEVATED_BG = \"#FFFDF6\" if THEME == \"light\" else \"#242420\"\nINK = \"#1A1A17\" if THEME == \"light\" else \"#F0EFE8\"\nINK_SOFT = \"#4A4A44\" if THEME == \"light\" else \"#B8B7B0\"\nINK_MUTED = \"#6B6A63\" if THEME == \"light\" else \"#A8A79F\"\n\n# Imprint palette base colors for level-1 departments (positions 1-3)\nIMPRINT = [\"#009E73\", \"#C475FD\", \"#4467A3\"]\nIMPRINT_RGB = [tuple(int(c[j : j + 2], 16) / 255 for j in (1, 3, 5)) for c in IMPRINT]\n\n# Data: Company budget breakdown ($thousands)\ndata = {\n    \"Engineering\": {\n        \"Frontend\": {\"Web App\": 150, \"Mobile\": 120},\n        \"Backend\": {\"API\": 180, \"Database\": 90},\n        \"DevOps\": {\"Cloud\": 100, \"CI/CD\": 60},\n    },\n    \"Sales\": {\"North\": {\"Enterprise\": 200, \"SMB\": 80}, \"South\": {\"Enterprise\": 150, \"SMB\": 70}},\n    \"Marketing\": {\"Digital\": {\"SEO\": 60, \"Ads\": 140}, \"Brand\": {\"Events\": 80, \"Content\": 50}},\n}\n\n# Build flat lists per ring, tracking which department each slice belongs to\nlevel1_names, level1_values, level1_colors = [], [], []\nlevel2_names, level2_values, level2_colors, level2_dept = [], [], [], []\nlevel3_names, level3_values, level3_colors, level3_dept = [], [], [], []\n\nfor i, (dept, teams) in enumerate(data.items()):\n    dept_total = sum(sum(projs.values()) for projs in teams.values())\n    level1_names.append(dept)\n    level1_values.append(dept_total)\n    level1_colors.append(IMPRINT[i])\n\n    r, g, b = IMPRINT_RGB[i]\n    team_items = list(teams.items())\n    n_teams = len(team_items)\n    for j, (team, projects) in enumerate(team_items):\n        team_total = sum(projects.values())\n        level2_names.append(team)\n        level2_values.append(team_total)\n        level2_dept.append(i)\n        f2 = 0.38 + 0.12 * j / max(n_teams - 1, 1)\n        level2_colors.append((min(1, r + (1 - r) * f2), min(1, g + (1 - g) * f2), min(1, b + (1 - b) * f2)))\n\n        proj_items = list(projects.items())\n        n_projs = len(proj_items)\n        for k, (proj, value) in enumerate(proj_items):\n            level3_names.append(proj)\n            level3_values.append(value)\n            level3_dept.append(i)\n            f3 = 0.58 + 0.12 * k / max(n_projs - 1, 1)\n            level3_colors.append((min(1, r + (1 - r) * f3), min(1, g + (1 - g) * f3), min(1, b + (1 - b) * f3)))\n\n# Focal point: the department that takes the largest share of the budget\ntotal_budget = sum(level1_values)\ntop_idx = int(np.argmax(level1_values))\ntop_share = level1_values[top_idx] / total_budget\n\n# Plot — square canvas for radial chart\nfig, ax = plt.subplots(figsize=(6, 6), dpi=400, facecolor=PAGE_BG)\nax.set_facecolor(PAGE_BG)\n\nring_width = 0.35\ninner_radius = 0.25\nouter_radius = inner_radius + 3 * ring_width\n\n# Level 3 (outermost ring)\nwedges3, _ = ax.pie(\n    level3_values,\n    radius=outer_radius,\n    colors=level3_colors,\n    startangle=90,\n    counterclock=False,\n    wedgeprops={\"width\": ring_width, \"edgecolor\": PAGE_BG, \"linewidth\": 2.5},\n)\n\n# Level 2 (middle ring)\nwedges2, _ = ax.pie(\n    level2_values,\n    radius=inner_radius + 2 * ring_width,\n    colors=level2_colors,\n    startangle=90,\n    counterclock=False,\n    wedgeprops={\"width\": ring_width, \"edgecolor\": PAGE_BG, \"linewidth\": 2.5},\n)\n\n# Level 1 (innermost ring) with department labels inside wedges\nwedges1, texts1 = ax.pie(\n    level1_values,\n    radius=inner_radius + ring_width,\n    colors=level1_colors,\n    labels=level1_names,\n    labeldistance=0.55,\n    startangle=90,\n    counterclock=False,\n    wedgeprops={\"width\": ring_width, \"edgecolor\": PAGE_BG, \"linewidth\": 2.5},\n    textprops={\"fontsize\": 11, \"fontweight\": \"bold\", \"color\": \"white\"},\n)\n\n# Emphasize the largest department across all three rings — the chart's focal point\nwedges1[top_idx].set_edgecolor(INK)\nwedges1[top_idx].set_linewidth(3.5)\nfor i, wedge in enumerate(wedges2):\n    if level2_dept[i] == top_idx:\n        wedge.set_edgecolor(INK)\n        wedge.set_linewidth(3)\nfor i, wedge in enumerate(wedges3):\n    if level3_dept[i] == top_idx:\n        wedge.set_edgecolor(INK)\n        wedge.set_linewidth(2.5)\n\n# Level 2 segment labels (positioned at ring midpoint) — stroke halo keeps\n# theme-adaptive ink legible against the (theme-constant) tinted ring fill\nfor i, wedge in enumerate(wedges2):\n    ang = (wedge.theta2 + wedge.theta1) / 2\n    r_mid = inner_radius + 1.5 * ring_width\n    x = r_mid * np.cos(np.radians(ang))\n    y = r_mid * np.sin(np.radians(ang))\n    if (wedge.theta2 - wedge.theta1) > 15:\n        ax.text(\n            x,\n            y,\n            level2_names[i],\n            ha=\"center\",\n            va=\"center\",\n            fontsize=9,\n            fontweight=\"medium\",\n            color=INK_SOFT,\n            path_effects=[pe.withStroke(linewidth=2.5, foreground=PAGE_BG)],\n        )\n\n# Level 3 segment labels (outermost ring midpoint)\nfor i, wedge in enumerate(wedges3):\n    ang = (wedge.theta2 + wedge.theta1) / 2\n    r_mid = inner_radius + 2.5 * ring_width\n    x = r_mid * np.cos(np.radians(ang))\n    y = r_mid * np.sin(np.radians(ang))\n    if (wedge.theta2 - wedge.theta1) > 12:\n        ax.text(\n            x,\n            y,\n            level3_names[i],\n            ha=\"center\",\n            va=\"center\",\n            fontsize=8,\n            color=INK_MUTED,\n            path_effects=[pe.withStroke(linewidth=2, foreground=PAGE_BG)],\n        )\n\n# Center hole: total budget as a grounding reference figure\nax.text(0, 0, f\"${total_budget:,}k\", ha=\"center\", va=\"center\", fontsize=10, fontweight=\"bold\", color=INK)\n\nax.set_aspect(\"equal\")\n\n# Key-insight caption (axes-fraction coords — independent of the pie's data\n# limits, so it can never clip regardless of wedge geometry): the focal point\n# the bold ink outline on the largest department draws the eye to.\nax.text(\n    0.5,\n    -0.03,\n    f\"{level1_names[top_idx]} is the largest department at {top_share:.0%} of the ${total_budget:,}k budget\",\n    transform=ax.transAxes,\n    ha=\"center\",\n    va=\"top\",\n    fontsize=9,\n    fontweight=\"bold\",\n    color=INK,\n    bbox={\n        \"boxstyle\": \"round,pad=0.5\",\n        \"facecolor\": ELEVATED_BG,\n        \"edgecolor\": INK_SOFT,\n        \"linewidth\": 1.2,\n        \"alpha\": 0.95,\n    },\n)\n\ntitle = \"Company Budget · sunburst-basic · python · matplotlib · anyplot.ai\"\nax.set_title(title, fontsize=9, fontweight=\"bold\", pad=14, color=INK)\nfig.subplots_adjust(left=0.03, right=0.97, top=0.87, bottom=0.11)\n\n# Save — bbox_inches MUST stay default (None) so figsize x dpi hits 2400x2400 exactly\nplt.savefig(f\"plot-{THEME}.png\", dpi=400, facecolor=PAGE_BG)\n"}