{"spec_id":"line-yield-curve","library":"matplotlib","language":"python","code":"\"\"\" anyplot.ai\nline-yield-curve: Yield Curve (Interest Rate Term Structure)\nLibrary: matplotlib 3.10.9 | Python 3.13.13\nQuality: 89/100 | Updated: 2026-06-10\n\"\"\"\n\nimport os\n\nimport matplotlib.pyplot as plt\nimport numpy as np\n\n\n# Theme tokens — see default-style-guide.md \"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# Imprint palette — semantic exception applied:\n# #009E73 (brand green) = normal/healthy curve; #AE3030 (matte red) = inverted/recession signal\nBRAND = \"#009E73\"  # Jan 2022 normal curve — Imprint position 1\nINVERTED_COLOR = \"#AE3030\"  # Oct 2023 inverted curve — semantic red (recession indicator)\nNORM_COLOR = \"#C475FD\"  # Jan 2025 normalizing curve — Imprint position 2\n\n# Data — U.S. Treasury yield curves across three monetary-policy regimes\nmaturities = [\"1M\", \"3M\", \"6M\", \"1Y\", \"2Y\", \"3Y\", \"5Y\", \"7Y\", \"10Y\", \"20Y\", \"30Y\"]\nmaturity_years = np.array([1 / 12, 0.25, 0.5, 1, 2, 3, 5, 7, 10, 20, 30])\n\n# Normal upward-sloping curve (Jan 2022) — pre-hiking cycle\nyields_normal = np.array([0.08, 0.21, 0.47, 0.78, 1.18, 1.42, 1.72, 1.90, 1.93, 2.28, 2.25])\n\n# Inverted curve (Oct 2023) — peak-rate environment, recession signal\nyields_inverted = np.array([5.54, 5.55, 5.52, 5.46, 5.05, 4.80, 4.62, 4.65, 4.73, 5.07, 4.95])\n\n# Normalizing curve (Jan 2025) — Fed pivoting, curve re-steepening\nyields_normalizing = np.array([4.36, 4.34, 4.32, 4.22, 4.20, 4.23, 4.38, 4.47, 4.58, 4.85, 4.84])\n\n# Plot\nfig, ax = plt.subplots(figsize=(8, 4.5), dpi=400, facecolor=PAGE_BG)\nax.set_facecolor(PAGE_BG)\n\ncurves = [\n    (yields_normal, BRAND, \"Jan 2022 (Normal)\"),\n    (yields_inverted, INVERTED_COLOR, \"Oct 2023 (Inverted)\"),\n    (yields_normalizing, NORM_COLOR, \"Jan 2025 (Normalizing)\"),\n]\n\nfor yields, color, label in curves:\n    ax.plot(\n        maturity_years,\n        yields,\n        color=color,\n        linewidth=2.5,\n        label=label,\n        marker=\"o\",\n        markersize=7,\n        markeredgecolor=PAGE_BG,\n        markeredgewidth=1.0,\n    )\n\n# Shade inversion region: from 3M peak (5.55%) down to 5Y trough\ntrough_idx = 6  # index of 5Y maturity\nax.fill_between(\n    maturity_years[: trough_idx + 1],\n    yields_inverted[: trough_idx + 1],\n    yields_inverted[1],  # 3M peak = 5.55%\n    alpha=0.10,\n    color=INVERTED_COLOR,\n)\n\n# Annotation highlighting the inversion\nax.annotate(\n    \"Yield curve inversion\",\n    xy=(3, 4.80),\n    xytext=(8, 5.50),\n    fontsize=8,\n    color=INVERTED_COLOR,\n    fontweight=\"medium\",\n    arrowprops={\"arrowstyle\": \"->\", \"color\": INVERTED_COLOR, \"lw\": 1.2},\n)\n\n# Style\ntitle = \"line-yield-curve · python · matplotlib · anyplot.ai\"\ntitle_fontsize = max(8, round(12 * 67 / len(title))) if len(title) > 67 else 12\n\nax.set_xlabel(\"Maturity\", fontsize=10, color=INK)\nax.set_ylabel(\"Yield (%)\", fontsize=10, color=INK)\nax.set_title(title, fontsize=title_fontsize, fontweight=\"medium\", color=INK)\n\nax.set_xscale(\"log\")\nax.set_xticks(maturity_years)\nax.set_xticklabels(maturities)\nax.minorticks_off()\nax.tick_params(axis=\"x\", labelsize=8, colors=INK_SOFT, length=0)\nax.tick_params(axis=\"y\", labelsize=8, colors=INK_SOFT, length=0)\n\nax.spines[\"top\"].set_visible(False)\nax.spines[\"right\"].set_visible(False)\nfor s in (\"left\", \"bottom\"):\n    ax.spines[s].set_color(INK_SOFT)\n\nax.yaxis.grid(True, alpha=0.15, linewidth=0.8, color=INK)\n\nleg = ax.legend(fontsize=8, frameon=True, loc=\"lower right\")\nleg.get_frame().set_facecolor(ELEVATED_BG)\nleg.get_frame().set_edgecolor(INK_SOFT)\nplt.setp(leg.get_texts(), color=INK_SOFT)\n\nfig.subplots_adjust(left=0.09, right=0.97, top=0.93, bottom=0.12)\n\n# Save\nplt.savefig(f\"plot-{THEME}.png\", dpi=400, facecolor=PAGE_BG)\nplt.close()\n"}