{"spec_id":"climograph-walter-lieth","library":"matplotlib","language":"python","code":"\"\"\" anyplot.ai\nclimograph-walter-lieth: Walter-Lieth Climate Diagram\nLibrary: matplotlib 3.11.0 | Python 3.13.13\nQuality: 89/100 | Created: 2026-06-15\n\"\"\"\n\nimport os\nimport sys\n\n\n# This file is named matplotlib.py; remove its directory from sys.path so Python\n# finds the installed matplotlib package instead of this file.\n_here = os.path.abspath(os.path.dirname(__file__))\nsys.path[:] = [p for p in sys.path if (os.path.abspath(p) if p else os.getcwd()) != _here]\n\nimport matplotlib.patches as mpatches\nimport matplotlib.pyplot as plt\nimport numpy as np\n\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\"\n\n# Semantic color overrides — climate diagram convention takes precedence over Imprint ordinal\nTEMP_COLOR = \"#AE3030\"  # Imprint matte red — thermal warmth\nPRECIP_COLOR = \"#4467A3\"  # Imprint blue — water / precipitation\n\n# Station data — Erzurum, Turkey (1991–2020 climate normals, WMO 17096)\n# 4 frost months (J, F, M, D) showcase all four Walter-Lieth diagnostic zones\nstation_name = \"Erzurum\"\nstation_lat = \"39°55′N\"\nstation_elev = 1869  # m a.s.l.\nmonths_labels = [\"J\", \"F\", \"M\", \"A\", \"M\", \"J\", \"J\", \"A\", \"S\", \"O\", \"N\", \"D\"]\ntemp = np.array([-9.7, -8.0, -2.2, 7.0, 12.5, 16.8, 20.9, 20.7, 15.5, 9.2, 1.8, -5.3])\nprecip = np.array([21, 19, 36, 58, 71, 36, 11, 10, 22, 47, 39, 27])\n\ntemp_annual = float(np.mean(temp))\nprecip_annual = int(np.sum(precip))\n\n# Walter-Lieth scaling: 10 °C ↔ 20 mm (ratio 1:2)\n# Above 100 mm: compressed 10:1 — not reached in this dataset, handled for robustness\nprecip_te = np.where(precip <= 100, precip / 2.0, 50.0 + (precip - 100) / 10.0)\n\nx = np.arange(12)\ny_min = -15\ny_max = 50\n\n# Canvas — 3200 × 1800 px\nfig, ax = plt.subplots(figsize=(8, 4.5), dpi=400, facecolor=PAGE_BG)\nax2 = ax.twinx()  # right axis for precipitation (created early; transparent by default)\nax.set_facecolor(PAGE_BG)\n\n# Humid fills (P > T) — blue/hatched per Walter-Lieth convention\nax.fill_between(\n    x,\n    temp,\n    precip_te,\n    where=(precip_te >= temp),\n    facecolor=PRECIP_COLOR,\n    alpha=0.30,\n    hatch=\"///\",\n    edgecolor=PRECIP_COLOR,\n    interpolate=True,\n    zorder=2,\n)\n\n# Arid fills (T > P) — red/dotted per Walter-Lieth convention\nax.fill_between(\n    x,\n    temp,\n    precip_te,\n    where=(temp >= precip_te),\n    facecolor=TEMP_COLOR,\n    alpha=0.30,\n    hatch=\"...\",\n    edgecolor=TEMP_COLOR,\n    interpolate=True,\n    zorder=2,\n)\n\n# Data lines (drawn above fills)\nax.plot(x, temp, color=TEMP_COLOR, linewidth=2.5, zorder=4)\nax.plot(x, precip_te, color=PRECIP_COLOR, linewidth=2.5, zorder=4)\n\n# 0 °C reference line (freezing point)\nax.axhline(0, color=INK_SOFT, linewidth=0.8, alpha=0.45, linestyle=\"--\", zorder=1)\n\n# Subtle horizontal grid\nax.yaxis.grid(True, alpha=0.12, linewidth=0.7, color=INK, zorder=0)\n\n# Left axis — temperature (°C)\nax.set_xlim(-0.5, 11.5)\nax.set_ylim(y_min, y_max)\nax.set_xticks(x)\nax.set_xticklabels(months_labels, fontsize=8, color=INK_SOFT)\nax.tick_params(axis=\"x\", colors=INK_SOFT, labelcolor=INK_SOFT, length=0)\nax.set_yticks([-10, 0, 10, 20, 30, 40])\nax.tick_params(axis=\"y\", colors=INK_SOFT, labelcolor=INK_SOFT, labelsize=8, length=4)\nax.set_ylabel(\"Temperature (°C)\", fontsize=10, color=TEMP_COLOR, labelpad=6)\nax.set_xlabel(\"Month\", fontsize=10, color=INK, labelpad=6)\n\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\n# Right axis — precipitation (mm) at 2× the temperature scale\nax2.set_ylim(y_min * 2, y_max * 2)  # −30 to 100 mm\nax2.set_yticks([0, 20, 40, 60, 100])  # spec: 0, 20, 40, 60, 100\nax2.tick_params(axis=\"y\", colors=INK_SOFT, labelcolor=INK_SOFT, labelsize=8, length=4)\nax2.set_ylabel(\"Precipitation (mm)\", fontsize=10, color=PRECIP_COLOR, labelpad=8)\nax2.spines[\"top\"].set_visible(False)\nax2.spines[\"left\"].set_visible(False)\nax2.spines[\"bottom\"].set_visible(False)\nax2.spines[\"right\"].set_color(INK_SOFT)\n\n# Frost month indicator blocks at the bottom of the axes (Walter-Lieth baseline convention)\n# Solid dark bars from y_min upward for each frost month (mean T < 0 °C)\nfrost_band_height = 2.5\nfor i in range(12):\n    if temp[i] < 0:\n        ax.bar(i, frost_band_height, bottom=y_min, color=INK, width=0.85, zorder=5, linewidth=0, alpha=0.90)\n# Thin separator above the frost band\nax.axhline(y_min + frost_band_height, color=INK_SOFT, linewidth=0.5, alpha=0.25, zorder=4)\n\n# Station metadata header (upper-left text box)\nheader = (\n    f\"{station_name}   {station_lat}   {station_elev} m a.s.l.\\n\"\n    f\"Mean T = {temp_annual:.1f} °C     Total P = {precip_annual} mm   (1991–2020)\"\n)\nax.text(\n    0.02,\n    0.97,\n    header,\n    transform=ax.transAxes,\n    fontsize=8,\n    color=INK,\n    verticalalignment=\"top\",\n    linespacing=1.6,\n    bbox={\n        \"facecolor\": ELEVATED_BG,\n        \"edgecolor\": INK_SOFT,\n        \"alpha\": 0.88,\n        \"boxstyle\": \"round,pad=0.3\",\n        \"linewidth\": 0.6,\n    },\n)\n\n# Legend (below chart area)\nhumid_patch = mpatches.Patch(\n    facecolor=PRECIP_COLOR, hatch=\"///\", edgecolor=PRECIP_COLOR, alpha=0.5, label=\"Humid period (P > T scale)\"\n)\narid_patch = mpatches.Patch(\n    facecolor=TEMP_COLOR, hatch=\"...\", edgecolor=TEMP_COLOR, alpha=0.5, label=\"Arid period (T > P scale)\"\n)\nfrost_patch = mpatches.Patch(facecolor=INK, alpha=0.90, label=\"Frost months (T < 0 °C)\")\n\nleg = ax.legend(\n    handles=[humid_patch, arid_patch, frost_patch],\n    fontsize=8,\n    loc=\"upper center\",\n    ncol=3,\n    framealpha=0.9,\n    bbox_to_anchor=(0.5, -0.16),\n    edgecolor=INK_SOFT,\n)\nif leg:\n    leg.get_frame().set_facecolor(ELEVATED_BG)\n    leg.get_frame().set_edgecolor(INK_SOFT)\n    plt.setp(leg.get_texts(), color=INK_SOFT)\n\n# Title\ntitle = \"climograph-walter-lieth · python · matplotlib · anyplot.ai\"\nn = len(title)\ntitle_fontsize = max(8, round(12 * 67 / n)) if n > 67 else 12\nax.set_title(title, fontsize=title_fontsize, fontweight=\"medium\", color=INK, pad=8)\n\n# Margins: room for title (top), legend below axes (bottom), both y-axis labels (sides)\nfig.subplots_adjust(top=0.88, bottom=0.22, left=0.10, right=0.91)\n\n# Save\nplt.savefig(f\"plot-{THEME}.png\", dpi=400, facecolor=PAGE_BG)\nplt.close()\n"}