{"spec_id":"bar-horizontal","library":"altair","language":"python","code":"\"\"\" anyplot.ai\nbar-horizontal: Horizontal Bar Chart\nLibrary: altair 6.2.2 | Python 3.13.14\nQuality: 89/100 | Updated: 2026-08-05\n\"\"\"\n\nimport os\n\nimport altair as alt\nimport pandas as pd\nfrom PIL import Image\n\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\"\nBRAND = \"#009E73\"  # Imprint palette position 1 — always the first categorical series\n\n# Data: Top 10 programming languages by developer survey popularity\ndata = pd.DataFrame(\n    {\n        \"language\": [\"Python\", \"JavaScript\", \"Java\", \"C++\", \"C#\", \"TypeScript\", \"Go\", \"Rust\", \"Swift\", \"Kotlin\"],\n        \"popularity\": [28.5, 18.2, 15.8, 10.3, 8.7, 6.2, 4.8, 3.5, 2.4, 1.6],\n    }\n)\ndata[\"label\"] = data[\"popularity\"].map(lambda v: f\"{v:.1f}%\")\ndata[\"is_top\"] = data[\"popularity\"] == data[\"popularity\"].max()\n\n# Leave headroom on the value axis so end-of-bar labels never clip\nx_max = data[\"popularity\"].max() * 1.15\n\nhover = alt.selection_point(on=\"pointerover\", fields=[\"language\"], empty=False)\n\nbars = (\n    alt.Chart(data)\n    .mark_bar(cornerRadiusEnd=3, color=BRAND)\n    .encode(\n        x=alt.X(\n            \"popularity:Q\",\n            title=\"Popularity (%)\",\n            scale=alt.Scale(domain=[0, x_max]),\n            axis=alt.Axis(labelFontSize=10, titleFontSize=12),\n        ),\n        y=alt.Y(\n            \"language:N\",\n            title=\"Programming Language\",\n            sort=\"-x\",\n            axis=alt.Axis(labelFontSize=10, titleFontSize=12, ticks=False),\n        ),\n        opacity=alt.when(hover)\n        .then(alt.value(1.0))\n        .when(\"datum.is_top\")\n        .then(alt.value(0.95))\n        .otherwise(alt.value(0.75)),\n        tooltip=[\n            alt.Tooltip(\"language:N\", title=\"Language\"),\n            alt.Tooltip(\"popularity:Q\", title=\"Popularity (%)\", format=\".1f\"),\n        ],\n    )\n    .add_params(hover)\n)\n\nlabels = (\n    alt.Chart(data)\n    .mark_text(align=\"left\", dx=6)\n    .encode(\n        x=alt.X(\"popularity:Q\"),\n        y=alt.Y(\"language:N\", sort=\"-x\"),\n        text=\"label:N\",\n        size=alt.when(\"datum.is_top\").then(alt.value(12)).otherwise(alt.value(10)),\n        color=alt.when(\"datum.is_top\").then(alt.value(INK)).otherwise(alt.value(INK_SOFT)),\n    )\n)\n\n# Create horizontal bar chart with end-of-bar value labels and a pointer-hover highlight\nchart = (\n    (bars + labels)\n    .properties(\n        width=620,\n        height=320,\n        background=PAGE_BG,\n        title=alt.Title(\"bar-horizontal · python · altair · anyplot.ai\", fontSize=16, anchor=\"middle\", color=INK),\n    )\n    .configure_view(fill=PAGE_BG, strokeWidth=0)\n    .configure_axis(\n        domainColor=INK_SOFT, tickColor=INK_SOFT, gridColor=INK, gridOpacity=0.10, labelColor=INK_SOFT, titleColor=INK\n    )\n    .configure_title(color=INK)\n)\n\n# Save PNG, then pad (never crop) up to the exact canonical canvas\nchart.save(f\"plot-{THEME}.png\", scale_factor=4.0)\n\nTW, TH = 3200, 1800\n_img = Image.open(f\"plot-{THEME}.png\").convert(\"RGB\")\n_w, _h = _img.size\nif _w > TW or _h > TH:\n    raise SystemExit(\n        f\"altair vl-convert produced {_w}x{_h}, exceeds target {TW}x{TH}. \"\n        f\"Shrink chart .properties(width=, height=) values and re-render.\"\n    )\nif _w < TW or _h < TH:\n    _canvas = Image.new(\"RGB\", (TW, TH), PAGE_BG)\n    _canvas.paste(_img, ((TW - _w) // 2, (TH - _h) // 2))\n    _canvas.save(f\"plot-{THEME}.png\")\n\nchart.save(f\"plot-{THEME}.html\")\n"}