{"spec_id":"area-stacked-percent","library":"letsplot","language":"python","code":"\"\"\" anyplot.ai\narea-stacked-percent: 100% Stacked Area Chart\nLibrary: letsplot 4.9.0 | Python 3.13.13\nQuality: 90/100 | Updated: 2026-05-12\n\"\"\"\n\nimport os\n\nimport numpy as np\nimport pandas as pd\nfrom lets_plot import (\n    LetsPlot,\n    aes,\n    element_blank,\n    element_line,\n    element_rect,\n    element_text,\n    geom_area,\n    ggplot,\n    ggsize,\n    labs,\n    scale_fill_manual,\n    scale_x_continuous,\n    scale_y_continuous,\n    theme,\n    theme_minimal,\n)\nfrom lets_plot.export import ggsave\n\n\nLetsPlot.setup_html()\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\"\nGRID_COLOR = \"rgba(26,26,23,0.10)\" if THEME == \"light\" else \"rgba(240,239,232,0.10)\"\n\n# Okabe-Ito palette (first series is always #009E73)\nIMPRINT = [\"#009E73\", \"#C475FD\", \"#4467A3\", \"#BD8233\"]\n\n# Data - Market share evolution over 8 years\nnp.random.seed(42)\n\nyears = list(range(2016, 2024))\n\n# Simulate market share trends (values will be normalized to 100%)\ncompany_a = [40, 38, 42, 45, 48, 52, 55, 58]  # Growing leader\ncompany_b = [35, 36, 33, 30, 28, 25, 23, 22]  # Declining\ncompany_c = [15, 16, 15, 16, 15, 14, 13, 12]  # Stable small player\ncompany_d = [10, 10, 10, 9, 9, 9, 9, 8]  # Smallest, slight decline\n\n# Normalize to 100%\ntotals = [a + b + c + d for a, b, c, d in zip(company_a, company_b, company_c, company_d, strict=False)]\ncompany_a_pct = [a / t * 100 for a, t in zip(company_a, totals, strict=False)]\ncompany_b_pct = [b / t * 100 for b, t in zip(company_b, totals, strict=False)]\ncompany_c_pct = [c / t * 100 for c, t in zip(company_c, totals, strict=False)]\ncompany_d_pct = [d / t * 100 for d, t in zip(company_d, totals, strict=False)]\n\n# Create long-format dataframe for lets-plot\ndf = pd.DataFrame(\n    {\n        \"Year\": years * 4,\n        \"Share\": company_a_pct + company_b_pct + company_c_pct + company_d_pct,\n        \"Company\": [\"Company A\"] * 8 + [\"Company B\"] * 8 + [\"Company C\"] * 8 + [\"Company D\"] * 8,\n    }\n)\n\n# Set category order for proper stacking\ndf[\"Company\"] = pd.Categorical(\n    df[\"Company\"], categories=[\"Company D\", \"Company C\", \"Company B\", \"Company A\"], ordered=True\n)\n\n# Plot\nplot = (\n    ggplot(df, aes(x=\"Year\", y=\"Share\", fill=\"Company\"))\n    + geom_area(position=\"fill\", alpha=0.85)\n    + scale_fill_manual(values=IMPRINT)\n    + scale_x_continuous(breaks=list(range(2016, 2024)))\n    + scale_y_continuous(format=\".0%\")\n    + labs(x=\"Year\", y=\"Market Share (%)\", title=\"area-stacked-percent · letsplot · anyplot.ai\")\n    + theme_minimal()\n    + theme(\n        plot_background=element_rect(fill=PAGE_BG, color=PAGE_BG),\n        panel_background=element_rect(fill=PAGE_BG),\n        panel_grid_major=element_line(color=GRID_COLOR, size=0.3),\n        panel_grid_minor=element_blank(),\n        plot_title=element_text(size=24, color=INK),\n        axis_title=element_text(size=20, color=INK),\n        axis_text=element_text(size=16, color=INK_SOFT),\n        axis_line=element_line(color=INK_SOFT),\n        legend_background=element_rect(fill=ELEVATED_BG, color=INK_SOFT),\n        legend_text=element_text(size=16, color=INK_SOFT),\n        legend_title=element_text(size=16, color=INK),\n    )\n    + ggsize(1600, 900)\n)\n\n# Save PNG (scale=3 gives 4800x2700)\nggsave(plot, f\"plot-{THEME}.png\", path=\".\", scale=3)\n\n# Save HTML for interactivity\nggsave(plot, f\"plot-{THEME}.html\", path=\".\")\n"}