{"spec_id":"histogram-stacked","library":"plotly","language":"python","code":"\"\"\" anyplot.ai\nhistogram-stacked: Stacked Histogram\nLibrary: plotly 6.7.0 | Python 3.13.13\nQuality: 91/100 | Updated: 2026-05-12\n\"\"\"\n\nimport os\nimport sys\n\nimport numpy as np\n\n\ntry:\n    import plotly.graph_objects as go\nexcept ModuleNotFoundError:\n    # Remove current directory from sys.path to avoid importing this script as 'plotly'\n    sys.path = [p for p in sys.path if p != \"\" and os.path.abspath(p) != os.path.dirname(os.path.abspath(__file__))]\n    import plotly.graph_objects as go\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\"\nGRID = \"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\"]\n\n# Data - Product weights from three production lines\nnp.random.seed(42)\nn_per_group = 150\n\n# Three production lines with different weight distributions\nline_a = np.random.normal(loc=250, scale=30, size=n_per_group)\nline_b = np.random.normal(loc=280, scale=25, size=n_per_group)\nline_c = np.random.normal(loc=260, scale=35, size=n_per_group)\n\n# Define consistent bin edges for all groups\nall_values = np.concatenate([line_a, line_b, line_c])\nbin_edges = np.histogram_bin_edges(all_values, bins=20)\n\n# Calculate histograms with same bins for proper stacking\nhist_a, _ = np.histogram(line_a, bins=bin_edges)\nhist_b, _ = np.histogram(line_b, bins=bin_edges)\nhist_c, _ = np.histogram(line_c, bins=bin_edges)\n\n# Bin centers for x-axis\nbin_centers = (bin_edges[:-1] + bin_edges[1:]) / 2\nbin_width = bin_edges[1] - bin_edges[0]\n\n# Create figure with stacked bars\nfig = go.Figure()\n\nfig.add_trace(\n    go.Bar(\n        x=bin_centers,\n        y=hist_a,\n        name=\"Line A\",\n        marker_color=IMPRINT[0],\n        width=bin_width * 0.9,\n        hovertemplate=\"<b>Line A</b><br>Weight: %{x:.1f}g<br>Count: %{y}<extra></extra>\",\n    )\n)\n\nfig.add_trace(\n    go.Bar(\n        x=bin_centers,\n        y=hist_b,\n        name=\"Line B\",\n        marker_color=IMPRINT[1],\n        width=bin_width * 0.9,\n        hovertemplate=\"<b>Line B</b><br>Weight: %{x:.1f}g<br>Count: %{y}<extra></extra>\",\n    )\n)\n\nfig.add_trace(\n    go.Bar(\n        x=bin_centers,\n        y=hist_c,\n        name=\"Line C\",\n        marker_color=IMPRINT[2],\n        width=bin_width * 0.9,\n        hovertemplate=\"<b>Line C</b><br>Weight: %{x:.1f}g<br>Count: %{y}<extra></extra>\",\n    )\n)\n\n# Layout with theme-adaptive styling\nfig.update_layout(\n    title=dict(text=\"histogram-stacked · plotly · anyplot.ai\", font=dict(size=28, color=INK), x=0.5, xanchor=\"center\"),\n    xaxis=dict(\n        title=dict(text=\"Product Weight (g)\", font=dict(size=22, color=INK)),\n        tickfont=dict(size=18, color=INK_SOFT),\n        gridcolor=GRID,\n        linecolor=INK_SOFT,\n        zerolinecolor=INK_SOFT,\n    ),\n    yaxis=dict(\n        title=dict(text=\"Frequency\", font=dict(size=22, color=INK)),\n        tickfont=dict(size=18, color=INK_SOFT),\n        gridcolor=GRID,\n        linecolor=INK_SOFT,\n        zerolinecolor=INK_SOFT,\n    ),\n    barmode=\"stack\",\n    paper_bgcolor=PAGE_BG,\n    plot_bgcolor=PAGE_BG,\n    legend=dict(\n        font=dict(size=16, color=INK_SOFT),\n        x=0.98,\n        y=0.98,\n        xanchor=\"right\",\n        yanchor=\"top\",\n        bgcolor=ELEVATED_BG,\n        bordercolor=INK_SOFT,\n        borderwidth=1,\n    ),\n    margin=dict(l=80, r=40, t=80, b=80),\n)\n\n# Save outputs\nfig.write_image(f\"plot-{THEME}.png\", width=1600, height=900, scale=3)\nfig.write_html(f\"plot-{THEME}.html\", include_plotlyjs=\"cdn\")\n"}