{"spec_id":"pie-basic","library":"plotnine","language":"python","code":"\"\"\" anyplot.ai\npie-basic: Basic Pie Chart\nLibrary: plotnine 0.15.4 | Python 3.13.13\nQuality: 81/100 | Created: 2026-05-28\n\"\"\"\n\nimport os\nimport sys\n\n\n# Remove this file's directory from sys.path to prevent self-import\n# (this file is named plotnine.py, same as the library being imported)\n_dir = os.path.dirname(os.path.abspath(__file__))\nsys.path = [p for p in sys.path if os.path.abspath(p) != _dir]\n\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport pandas as pd\nfrom plotnine import (\n    aes,\n    coord_equal,\n    element_rect,\n    element_text,\n    geom_polygon,\n    geom_text,\n    ggplot,\n    labs,\n    scale_fill_manual,\n    theme,\n    theme_void,\n)\n\n\n# Theme tokens\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\"\n\nIMPRINT_PALETTE = [\"#009E73\", \"#C475FD\", \"#4467A3\", \"#BD8233\", \"#AE3030\", \"#2ABCCD\"]\n\n# Data — annual R&D budget allocation by department\ndepartments = [\"R&D\", \"Marketing\", \"Operations\", \"Human Resources\", \"IT Infrastructure\", \"Administration\"]\nbudget_shares = [32, 22, 18, 13, 11, 4]\ntotal = sum(budget_shares)\n\n# Build pie wedge polygons starting at 12 o'clock, going clockwise\nN_ARC = 80\nEXPLODE_OFFSET = 0.07  # slight offset for the largest slice\n\nwedge_rows = []\nlabel_rows = []\n\ncumsum = 0\nfor cat, val in zip(departments, budget_shares, strict=False):\n    pct = val / total\n    # Clockwise from 12 o'clock: start at π/2, decrease by pct * 2π\n    start_angle = np.pi / 2 - 2 * np.pi * cumsum\n    end_angle = np.pi / 2 - 2 * np.pi * (cumsum + pct)\n    mid_angle = (start_angle + end_angle) / 2\n\n    # Explode largest slice (R&D) outward along its bisector\n    offset = EXPLODE_OFFSET if cat == \"R&D\" else 0.0\n    dx, dy = offset * np.cos(mid_angle), offset * np.sin(mid_angle)\n\n    # Wedge vertices: center → arc → (auto-closed by geom_polygon)\n    angles = np.linspace(start_angle, end_angle, N_ARC)\n    xs = np.concatenate([[0.0], np.cos(angles)]) + dx\n    ys = np.concatenate([[0.0], np.sin(angles)]) + dy\n\n    for xi, yi in zip(xs, ys, strict=False):\n        wedge_rows.append({\"x\": xi, \"y\": yi, \"category\": cat})\n\n    # Percentage label at 62% of radius, only show if slice >= 5%\n    if pct >= 0.05:\n        label_r = 0.62 + offset\n        label_rows.append(\n            {\n                \"x\": label_r * np.cos(mid_angle) + dx,\n                \"y\": label_r * np.sin(mid_angle) + dy,\n                \"label\": f\"{round(pct * 100)}%\",\n            }\n        )\n\n    cumsum += pct\n\ndf_wedges = pd.DataFrame(wedge_rows)\ndf_wedges[\"category\"] = pd.Categorical(df_wedges[\"category\"], categories=departments, ordered=True)\ndf_labels = pd.DataFrame(label_rows)\n\ntitle = \"pie-basic · python · plotnine · anyplot.ai\"\n\n# Plot\nplot = (\n    ggplot()\n    + geom_polygon(data=df_wedges, mapping=aes(x=\"x\", y=\"y\", fill=\"category\", group=\"category\"))\n    + geom_text(data=df_labels, mapping=aes(x=\"x\", y=\"y\", label=\"label\"), size=4.0, color=\"white\")\n    + scale_fill_manual(values=IMPRINT_PALETTE)\n    + coord_equal()\n    + labs(title=title, fill=\"Department\")\n    + theme_void()\n    + theme(\n        figure_size=(6, 6),\n        plot_background=element_rect(fill=PAGE_BG, color=PAGE_BG),\n        panel_background=element_rect(fill=PAGE_BG),\n        plot_title=element_text(size=12, color=INK, ha=\"center\"),\n        legend_text=element_text(size=8, color=INK_SOFT),\n        legend_title=element_text(size=10, color=INK),\n        legend_background=element_rect(fill=ELEVATED_BG, color=INK_SOFT),\n        legend_key=element_rect(fill=ELEVATED_BG, color=ELEVATED_BG),\n    )\n)\n\n# Draw and save — use subplots_adjust to give the right-side legend breathing room\nfig = plot.draw()\nfig.subplots_adjust(right=0.85)\nfig.savefig(f\"plot-{THEME}.png\", dpi=400)\nplt.close(fig)\n"}