{"spec_id":"bar-stacked-labeled","library":"seaborn","language":"python","code":"\"\"\" anyplot.ai\nbar-stacked-labeled: Stacked Bar Chart with Total Labels\nLibrary: seaborn 0.13.2 | Python 3.13.13\nQuality: 86/100 | Updated: 2026-05-18\n\"\"\"\n\nimport os\n\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport pandas as pd\nimport seaborn as sns\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\n# Okabe-Ito palette - first series is always #009E73\nIMPRINT = [\"#009E73\", \"#C475FD\", \"#4467A3\", \"#BD8233\"]\n\n# Configure seaborn theme\nsns.set_theme(\n    style=\"ticks\",\n    rc={\n        \"figure.facecolor\": PAGE_BG,\n        \"axes.facecolor\": PAGE_BG,\n        \"axes.edgecolor\": INK_SOFT,\n        \"axes.labelcolor\": INK,\n        \"text.color\": INK,\n        \"xtick.color\": INK_SOFT,\n        \"ytick.color\": INK_SOFT,\n        \"grid.color\": INK,\n        \"grid.alpha\": 0.10,\n        \"legend.facecolor\": ELEVATED_BG,\n        \"legend.edgecolor\": INK_SOFT,\n    },\n)\n\n# Data - Quarterly revenue by product category (varied growth patterns)\nnp.random.seed(42)\n\ncategories = [\"Q1\", \"Q2\", \"Q3\", \"Q4\"]\ncomponents = [\"Electronics\", \"Software\", \"Services\", \"Hardware\"]\n\n# Create data with realistic revenue values (in millions) with varied patterns\ndata = {\n    \"Electronics\": [45, 52, 48, 61],\n    \"Software\": [32, 38, 42, 55],\n    \"Services\": [28, 31, 35, 40],\n    \"Hardware\": [18, 22, 19, 28],\n}\n\n# Create stacked bar data\ndf_wide = pd.DataFrame(data, index=categories)\n\n# Calculate totals for each quarter\ntotals = df_wide.sum(axis=1)\n\n# Plot\nfig, ax = plt.subplots(figsize=(16, 9), facecolor=PAGE_BG)\nax.set_facecolor(PAGE_BG)\n\n# Create stacked bars\nbottom = np.zeros(len(categories))\nbars_list = []\n\nfor idx, comp in enumerate(components):\n    bars = ax.bar(\n        categories, df_wide[comp], bottom=bottom, label=comp, color=IMPRINT[idx], edgecolor=PAGE_BG, linewidth=1.5\n    )\n    bars_list.append(bars)\n    bottom += df_wide[comp].values\n\n# Add total labels above each bar stack\nfor i, total in enumerate(totals):\n    ax.annotate(\n        f\"${total:.0f}M\",\n        xy=(i, total),\n        xytext=(0, 12),\n        textcoords=\"offset points\",\n        ha=\"center\",\n        va=\"bottom\",\n        fontsize=18,\n        fontweight=\"bold\",\n        color=INK,\n    )\n\n# Styling\nax.set_xlabel(\"Quarter\", fontsize=20, color=INK)\nax.set_ylabel(\"Revenue (Millions USD)\", fontsize=20, color=INK)\nax.set_title(\"bar-stacked-labeled · Python · seaborn · anyplot.ai\", fontsize=24, pad=20, color=INK)\nax.tick_params(axis=\"both\", labelsize=16, colors=INK_SOFT)\n\n# Legend - positioned to avoid overlap with bars\nax.legend(\n    title=\"Product Category\",\n    title_fontsize=16,\n    fontsize=14,\n    loc=\"upper right\",\n    framealpha=1.0,\n    facecolor=ELEVATED_BG,\n    edgecolor=INK_SOFT,\n)\n\n# Grid - subtle horizontal only\nax.yaxis.grid(True, alpha=0.10, linewidth=0.8)\nax.set_axisbelow(True)\n\n# Adjust y-axis limit to accommodate labels\nax.set_ylim(0, max(totals) * 1.15)\n\n# Remove top and right spines for cleaner look\nsns.despine(ax=ax)\n\nplt.tight_layout()\nplt.savefig(f\"plot-{THEME}.png\", dpi=300, bbox_inches=\"tight\", facecolor=PAGE_BG)\n"}