{"spec_id":"bar-heart-rate-zones","library":"matplotlib","language":"python","code":"\"\"\" anyplot.ai\nbar-heart-rate-zones: Time in Heart Rate Zones Bar Chart\nLibrary: matplotlib 3.11.0 | Python 3.13.13\nQuality: 89/100 | Created: 2026-06-14\n\"\"\"\n\nimport os\nimport pathlib\nimport sys\n\n\n# Remove this script's directory from sys.path so `import matplotlib` resolves\n# to the installed package, not this file (which shares the name).\n_HERE = str(pathlib.Path(__file__).parent.resolve())\nsys.path = [p for p in sys.path if p != _HERE]\n\nimport matplotlib.pyplot as plt\nimport numpy as np\n\n\n# Save outputs next to this script regardless of CWD\n_OUT = pathlib.Path(__file__).parent\n\n# Theme tokens (Imprint palette — theme-adaptive chrome)\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\"\nINK_MUTED = \"#6B6A63\" if THEME == \"light\" else \"#A8A79F\"\n\n# Semantic zone colors — fitness convention: grey / blue / green / ochre / red\n# Imprint palette members chosen by semantic exception (each zone has a strong hue convention)\nZONE_COLORS = [INK_MUTED, \"#4467A3\", \"#009E73\", \"#BD8233\", \"#AE3030\"]\n\n# Data — 60-minute tempo run\nzone_ids = [\"Z1\", \"Z2\", \"Z3\", \"Z4\", \"Z5\"]\nzone_names = [\"Recovery\", \"Endurance\", \"Aerobic\", \"Threshold\", \"Maximum\"]\nminutes = [8, 22, 15, 12, 3]\nhr_ranges = [\"< 115 bpm\", \"115–138 bpm\", \"138–156 bpm\", \"156–169 bpm\", \"> 169 bpm\"]\n\nbar_labels = [f\"{m} min\" for m in minutes]\ntick_labels = [f\"{zid}  {name}\\n{hr}\" for zid, name, hr in zip(zone_ids, zone_names, hr_ranges, strict=True)]\n\n# Plot\nx = np.arange(len(zone_ids))\nfig, ax = plt.subplots(figsize=(8, 4.5), dpi=400, facecolor=PAGE_BG)\nax.set_facecolor(PAGE_BG)\n\nbars = ax.bar(x, minutes, color=ZONE_COLORS, width=0.55, zorder=2, edgecolor=PAGE_BG, linewidth=1.5)\n\n# Emphasize the dominant Z2 bar (highest duration — 22 min)\ndominant_idx = minutes.index(max(minutes))\nbars[dominant_idx].set_edgecolor(INK)\nbars[dominant_idx].set_linewidth(2.0)\nbars[dominant_idx].set_zorder(3)\n\n# Idiomatic bar labels via ax.bar_label() (available since matplotlib 3.4)\nax.bar_label(bars, labels=bar_labels, fontsize=9, fontweight=\"bold\", padding=4, color=INK)\n\n# Style\ntitle = \"bar-heart-rate-zones · python · matplotlib · anyplot.ai\"\nax.set_title(title, fontsize=12, fontweight=\"medium\", color=INK, pad=14)\nax.set_ylabel(\"Time (minutes)\", fontsize=10, color=INK, labelpad=10)\nax.set_xlabel(\"Heart Rate Training Zone\", fontsize=10, color=INK, labelpad=14)\n\nax.set_xticks(x)\nax.tick_params(axis=\"both\", which=\"both\", length=0, labelsize=9, labelcolor=INK_SOFT)\nax.set_xticklabels(tick_labels, fontsize=9, color=INK_SOFT)\n\nax.yaxis.grid(True, alpha=0.15, linewidth=0.8, color=INK, zorder=0)\nax.spines[\"top\"].set_visible(False)\nax.spines[\"right\"].set_visible(False)\nax.spines[\"left\"].set_color(INK_SOFT)\nax.spines[\"bottom\"].set_color(INK_SOFT)\n\nax.set_xlim(-0.6, 4.6)\nax.set_ylim(0, max(minutes) * 1.22)\n\n# Total training time — anchors the workout narrative\nax.text(\n    0.98,\n    0.97,\n    \"Total: 60 min\",\n    ha=\"right\",\n    va=\"top\",\n    transform=ax.transAxes,\n    fontsize=9,\n    fontweight=\"medium\",\n    color=INK_SOFT,\n)\n\nfig.subplots_adjust(left=0.12, right=0.97, top=0.88, bottom=0.24)\n\n# Save\nplt.savefig(_OUT / f\"plot-{THEME}.png\", dpi=400, facecolor=PAGE_BG)\nplt.close()\n"}