{"spec_id":"span-basic","library":"plotnine","language":"python","code":"\"\"\" anyplot.ai\nspan-basic: Basic Span Plot (Highlighted Region)\nLibrary: plotnine 0.15.7 | Python 3.13.14\nQuality: 88/100 | Updated: 2026-07-25\n\"\"\"\n\nimport os\n\nimport numpy as np\nimport pandas as pd\nfrom plotnine import (\n    aes,\n    element_line,\n    element_rect,\n    element_text,\n    geom_line,\n    geom_rect,\n    geom_text,\n    ggplot,\n    labs,\n    scale_fill_manual,\n    theme,\n    theme_minimal,\n)\n\n\n# Theme tokens\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\nIMPRINT = [\"#009E73\", \"#C475FD\", \"#4467A3\", \"#BD8233\", \"#AE3030\", \"#2ABCCD\", \"#954477\"]\n\n# Data - Stock prices over 10 years with highlighted periods\nnp.random.seed(42)\nyears = np.linspace(2006, 2016, 100)\nprice = 100 + np.cumsum(np.random.randn(100) * 2)\nrecession_mask = (years >= 2008) & (years < 2010)\nprice[recession_mask] -= np.linspace(0, 25, recession_mask.sum())\nprice[years >= 2010] -= 25\nprice = price + np.abs(price.min()) + 50\n\ndf = pd.DataFrame({\"year\": years, \"price\": price})\n\ny_min = df[\"price\"].min() - 5\ny_max = df[\"price\"].max() + 5\nx_min = years.min()\nx_max = years.max()\n\nspans = pd.DataFrame(\n    {\n        \"xmin\": [2008, x_min],\n        \"xmax\": [2009, x_max],\n        \"ymin\": [y_min, 145],\n        \"ymax\": [y_max, 165],\n        \"label\": [\"Recession Period\", \"Risk Zone\"],\n    }\n)\n\nannotation = pd.DataFrame({\"x\": [x_max - 0.3], \"y\": [167], \"text\": [\"Risk Threshold\"]})\n\n# Plot\nplot = (\n    ggplot()\n    + geom_rect(data=spans, mapping=aes(xmin=\"xmin\", xmax=\"xmax\", ymin=\"ymin\", ymax=\"ymax\", fill=\"label\"), alpha=0.25)\n    + geom_line(data=df, mapping=aes(x=\"year\", y=\"price\"), color=IMPRINT[0], size=1.2)\n    + geom_text(data=annotation, mapping=aes(x=\"x\", y=\"y\", label=\"text\"), ha=\"right\", size=7, color=INK_SOFT)\n    + scale_fill_manual(values={\"Recession Period\": IMPRINT[1], \"Risk Zone\": IMPRINT[2]}, name=\"Highlighted Region\")\n    + labs(x=\"Year\", y=\"Price ($)\", title=\"span-basic · plotnine · anyplot.ai\")\n    + theme_minimal()\n    + theme(\n        figure_size=(8, 4.5),\n        text=element_text(size=7),\n        plot_background=element_rect(fill=PAGE_BG, color=PAGE_BG),\n        panel_background=element_rect(fill=PAGE_BG),\n        plot_title=element_text(size=12, color=INK),\n        axis_title=element_text(size=10, color=INK),\n        axis_text=element_text(size=8, color=INK_SOFT),\n        legend_text=element_text(size=8, color=INK_SOFT),\n        legend_title=element_text(size=9, color=INK),\n        legend_background=element_rect(fill=ELEVATED_BG, color=INK_SOFT),\n        panel_grid_major=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    )\n)\n\n# Save\nplot.save(f\"plot-{THEME}.png\", dpi=400, width=8, height=4.5, units=\"in\", verbose=False)\n"}