{"spec_id":"line-annotated-events","library":"matplotlib","language":"python","code":"\"\"\" anyplot.ai\nline-annotated-events: Annotated Line Plot with Event Markers\nLibrary: matplotlib 3.10.9 | Python 3.13.13\nQuality: 91/100 | Updated: 2026-05-16\n\"\"\"\n\nimport os\n\nimport matplotlib.lines as mlines\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport pandas as pd\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\"\nBRAND = \"#009E73\"\n\n# Data\nnp.random.seed(42)\ndates = pd.date_range(\"2024-01-01\", periods=365, freq=\"D\")\nbase_price = 150\nreturns = np.random.randn(365) * 0.015\nprices = base_price * np.cumprod(1 + returns)\n\n# Event dates and labels\nevents = [\n    (pd.Timestamp(\"2024-02-15\"), \"Q4 2023\\nEarnings\"),\n    (pd.Timestamp(\"2024-05-10\"), \"Q1 2024\\nEarnings\"),\n    (pd.Timestamp(\"2024-07-22\"), \"Product\\nLaunch\"),\n    (pd.Timestamp(\"2024-08-08\"), \"Q2 2024\\nEarnings\"),\n    (pd.Timestamp(\"2024-11-14\"), \"Q3 2024\\nEarnings\"),\n]\n\n# Plot\nfig, ax = plt.subplots(figsize=(16, 9), facecolor=PAGE_BG)\nax.set_facecolor(PAGE_BG)\n\n# Main line in brand color\nax.plot(dates, prices, linewidth=3, color=BRAND, label=\"Stock Price\", zorder=2)\n\n# Event markers with alternating heights\nevent_color = \"#C475FD\" if THEME == \"light\" else \"#2ABCCD\"\nheights = [0.85, 0.70, 0.85, 0.70, 0.85]\n\nfor i, (event_date, event_label) in enumerate(events):\n    # Vertical dashed line for event\n    ax.axvline(x=event_date, color=event_color, linestyle=\"--\", linewidth=2.5, alpha=0.7, zorder=1)\n\n    # Text annotation with FancyBboxPatch-style box\n    y_pos = ax.get_ylim()[0] + (ax.get_ylim()[1] - ax.get_ylim()[0]) * heights[i]\n    ax.annotate(\n        event_label,\n        xy=(event_date, prices[dates.get_loc(event_date)]),\n        xytext=(event_date, y_pos),\n        fontsize=14,\n        ha=\"center\",\n        va=\"bottom\",\n        color=INK,\n        bbox={\"boxstyle\": \"round,pad=0.5\", \"facecolor\": ELEVATED_BG, \"edgecolor\": event_color, \"linewidth\": 1.5, \"alpha\": 0.95},\n        arrowprops={\"arrowstyle\": \"->\", \"color\": event_color, \"lw\": 1.5, \"alpha\": 0.7},\n    )\n\n# Styling\nax.set_xlabel(\"Date\", fontsize=20, color=INK)\nax.set_ylabel(\"Price (USD)\", fontsize=20, color=INK)\nax.set_title(\"line-annotated-events · matplotlib · anyplot.ai\", fontsize=24, color=INK)\nax.tick_params(axis=\"both\", labelsize=16, colors=INK_SOFT, labelcolor=INK_SOFT)\n\n# Grid\nax.yaxis.grid(True, alpha=0.15, linewidth=0.8, color=INK_SOFT)\n\n# Spines\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    ax.spines[s].set_linewidth(1.2)\n\n# Legend with proper Line2D proxy for event marker\nevent_line = mlines.Line2D([], [], color=event_color, linestyle=\"--\", linewidth=2.5, label=\"Event Marker\", alpha=0.7)\nax.legend(\n    handles=[ax.get_lines()[0], event_line],\n    fontsize=16,\n    loc=\"upper left\",\n    frameon=True,\n    facecolor=ELEVATED_BG,\n    edgecolor=INK_SOFT,\n    framealpha=0.95,\n)\n\n# Format x-axis for date readability\nfig.autofmt_xdate(rotation=30, ha=\"right\")\n\nplt.tight_layout()\nplt.savefig(f\"plot-{THEME}.png\", dpi=300, bbox_inches=\"tight\", facecolor=PAGE_BG)\n"}