{"spec_id":"bar-diverging","library":"plotnine","language":"python","code":"\"\"\" anyplot.ai\nbar-diverging: Diverging Bar Chart\nLibrary: plotnine 0.15.8 | Python 3.13.15\nQuality: 89/100 | Updated: 2026-08-18\n\"\"\"\n\nimport importlib.util\nimport os\nimport sys\n\nimport pandas as pd\n\n\n# Handle import conflicts: remove current dir and cache\nsys.path = [p for p in sys.path if not p.endswith(\"python\")]\nif \"plotnine\" in sys.modules:\n    del sys.modules[\"plotnine\"]\n\n# Import plotnine explicitly from site-packages\nplotnine_spec = importlib.util.find_spec(\"plotnine\")\nplotnine = importlib.util.module_from_spec(plotnine_spec)\nsys.modules[\"plotnine\"] = plotnine\nplotnine_spec.loader.exec_module(plotnine)\n\naes = plotnine.aes\ncoord_flip = plotnine.coord_flip\nelement_line = plotnine.element_line\nelement_rect = plotnine.element_rect\nelement_text = plotnine.element_text\ngeom_bar = plotnine.geom_bar\ngeom_hline = plotnine.geom_hline\ngeom_text = plotnine.geom_text\nggplot = plotnine.ggplot\nlabs = plotnine.labs\nscale_fill_manual = plotnine.scale_fill_manual\ntheme = plotnine.theme\ntheme_minimal = plotnine.theme_minimal\n\nTHEME = os.getenv(\"ANYPLOT_THEME\", \"light\")\nPAGE_BG = \"#FAF8F1\" if THEME == \"light\" else \"#1A1A17\"\nINK = \"#1A1A17\" if THEME == \"light\" else \"#F0EFE8\"\nINK_SOFT = \"#4A4A44\" if THEME == \"light\" else \"#B8B7B0\"\n\n# Data - Customer satisfaction survey across product categories\ncategories = [\n    \"Mobile App\",\n    \"Customer Service\",\n    \"Website\",\n    \"Delivery Speed\",\n    \"Product Quality\",\n    \"Pricing\",\n    \"Return Policy\",\n    \"Packaging\",\n    \"Email Support\",\n    \"Chat Support\",\n    \"Documentation\",\n    \"Warranty\",\n]\n\nvalues = [72, 45, 38, 25, 18, 8, -5, -12, -22, -35, -48, -62]\n\ndf = pd.DataFrame({\"category\": categories, \"value\": values})\n\n# Sort by value for better pattern recognition\ndf = df.sort_values(\"value\", ascending=True).reset_index(drop=True)\n\n# Create ordered categorical for proper sorting in plot\ndf[\"category\"] = pd.Categorical(df[\"category\"], categories=df[\"category\"], ordered=True)\n\n# Color based on positive/negative (Imprint palette, semantic red/green anchors)\ndf[\"sentiment\"] = df[\"value\"].apply(lambda x: \"Positive\" if x >= 0 else \"Negative\")\n\n# Value labels give a redundant, color-independent cue for direction/magnitude\n# (not just hue) and call out the standout categories (+72 leader, -62 laggard).\npos_df = df[df[\"value\"] >= 0].copy()\npos_df[\"label\"] = pos_df[\"value\"].apply(lambda v: f\"+{v}\")\nneg_df = df[df[\"value\"] < 0].copy()\nneg_df[\"label\"] = neg_df[\"value\"].apply(lambda v: f\"{v}\")\n\n# Plot\nplot = (\n    ggplot(df, aes(x=\"category\", y=\"value\", fill=\"sentiment\"))\n    + geom_bar(stat=\"identity\", width=0.7)\n    + geom_hline(yintercept=0, color=INK_SOFT, size=0.8)\n    + geom_text(pos_df, aes(y=\"value + 3\", label=\"label\"), color=INK_SOFT, size=7, ha=\"left\")\n    + geom_text(neg_df, aes(y=\"value - 3\", label=\"label\"), color=INK_SOFT, size=7, ha=\"right\")\n    + coord_flip()\n    + scale_fill_manual(values={\"Positive\": \"#009E73\", \"Negative\": \"#AE3030\"})\n    + labs(\n        x=\"Product Category\",\n        y=\"Net Satisfaction Score (%)\",\n        title=\"bar-diverging · python · plotnine · anyplot.ai\",\n        fill=\"Sentiment\",\n    )\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_y=element_line(color=INK, size=0.3, alpha=0.10),\n        panel_grid_minor=element_line(color=INK, size=0.2, alpha=0.05),\n        axis_title=element_text(color=INK, size=10),\n        axis_text=element_text(color=INK_SOFT, size=8),\n        plot_title=element_text(color=INK, size=12),\n        legend_background=element_rect(fill=PAGE_BG, color=INK_SOFT),\n        legend_text=element_text(color=INK_SOFT, size=8),\n        legend_title=element_text(color=INK, size=9),\n        figure_size=(8, 4.5),\n    )\n)\n\n# Save\nplot.save(f\"plot-{THEME}.png\", dpi=400, width=8, height=4.5, units=\"in\", verbose=False)\n"}