{"spec_id":"bar-error","library":"letsplot","language":"python","code":"\"\"\" anyplot.ai\nbar-error: Bar Chart with Error Bars\nLibrary: letsplot 4.9.0 | Python 3.13.13\nQuality: 85/100 | Updated: 2026-05-10\n\"\"\"\n\nimport os\n\nimport pandas as pd\nfrom lets_plot import (\n    LetsPlot,\n    aes,\n    element_line,\n    element_rect,\n    element_text,\n    geom_bar,\n    geom_errorbar,\n    ggplot,\n    ggsave,\n    ggsize,\n    labs,\n    scale_fill_manual,\n    theme,\n)\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.08)\" if THEME == \"light\" else \"rgba(240,239,232,0.08)\"\n\n# Okabe-Ito palette - first series is brand green\nIMPRINT = [\"#009E73\", \"#C475FD\", \"#4467A3\", \"#BD8233\", \"#AE3030\"]\n\n# Data: A/B test results showing conversion rates with 95% CI\ncategories = [\"Control\", \"Variant A\", \"Variant B\", \"Variant C\", \"Variant D\"]\nvalues = [12.3, 14.8, 11.2, 16.5, 13.9]\nerrors_lower = [1.2, 1.5, 1.0, 1.8, 1.4]\nerrors_upper = [1.4, 1.6, 1.1, 2.0, 1.5]\n\ndf = pd.DataFrame(\n    {\n        \"category\": categories,\n        \"value\": values,\n        \"ymin\": [v - el for v, el in zip(values, errors_lower, strict=True)],\n        \"ymax\": [v + eu for v, eu in zip(values, errors_upper, strict=True)],\n    }\n)\n\n# Create bar chart with error bars and enhanced design\nplot = (\n    ggplot(df, aes(x=\"category\", y=\"value\", fill=\"category\"))\n    + geom_bar(stat=\"identity\", width=0.68, show_legend=False, alpha=0.92)\n    + geom_errorbar(aes(ymin=\"ymin\", ymax=\"ymax\"), width=0.23, size=1.3, color=INK_SOFT, alpha=0.85)\n    + scale_fill_manual(values=IMPRINT)\n    + labs(\n        title=\"bar-error · letsplot · anyplot.ai\",\n        x=\"Test Group\",\n        y=\"Conversion Rate (%)\",\n        caption=\"Error bars show 95% CI | Interactive HTML export available\",\n    )\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_y=element_line(color=GRID_COLOR, size=0.22),\n        panel_grid_major_x=element_line(color=\"transparent\"),\n        panel_grid_minor=element_line(color=\"transparent\"),\n        axis_title=element_text(size=20, color=INK),\n        axis_text=element_text(size=16, color=INK_SOFT),\n        plot_title=element_text(size=24, color=INK),\n        plot_caption=element_text(size=14, color=INK_SOFT),\n    )\n    + ggsize(1600, 900)\n)\n\n# Save as PNG and HTML with theme suffix\nggsave(plot, f\"plot-{THEME}.png\", path=\".\", scale=3)\nggsave(plot, f\"plot-{THEME}.html\", path=\".\")\n"}