{"spec_id":"line-stock-comparison","library":"matplotlib","language":"python","code":"\"\"\" anyplot.ai\nline-stock-comparison: Stock Price Comparison Chart\nLibrary: matplotlib 3.10.9 | Python 3.13.13\nQuality: 89/100 | Updated: 2026-05-23\n\"\"\"\n\nimport os\nimport sys\n\n\n# matplotlib.py filename shadows the installed package; pop the script dir\n# so imports resolve to the site-packages installation.\n_script_dir = sys.path.pop(0)\nimport matplotlib.dates as mdates\nimport matplotlib.pyplot as plt\n\n\nsys.path.insert(0, _script_dir)\n\nimport numpy as np\nimport pandas as pd\n\n\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# Imprint palette — canonical order\nIMPRINT = [\"#009E73\", \"#C475FD\", \"#AE3030\", \"#4467A3\"]\n\n# Data — simulated daily stock prices for ~1 year (252 trading days)\nnp.random.seed(42)\nn_days = 252\ndates = pd.date_range(\"2024-01-02\", periods=n_days, freq=\"B\")\n\nstocks = {\n    \"AAPL\": {\"start\": 185, \"drift\": 0.0008, \"vol\": 0.018},\n    \"GOOGL\": {\"start\": 140, \"drift\": 0.0006, \"vol\": 0.020},\n    \"MSFT\": {\"start\": 375, \"drift\": 0.0007, \"vol\": 0.016},\n    \"SPY\": {\"start\": 475, \"drift\": 0.0004, \"vol\": 0.010},\n}\n\nrebased = {}\nfor symbol, params in stocks.items():\n    returns = np.random.normal(params[\"drift\"], params[\"vol\"], n_days)\n    price_series = params[\"start\"] * np.cumprod(1 + returns)\n    rebased[symbol] = price_series / price_series[0] * 100\n\n# Plot\nfig, ax = plt.subplots(figsize=(8, 4.5), dpi=400, facecolor=PAGE_BG)\nax.set_facecolor(PAGE_BG)\n\nfor (symbol, values), color in zip(rebased.items(), IMPRINT, strict=False):\n    # SPY is the benchmark — thicker line for emphasis and visual hierarchy\n    lw = 3.0 if symbol == \"SPY\" else 2.0\n    ax.plot(dates, values, label=symbol, color=color, linewidth=lw)\n\n# Reference line at 100 (starting point)\nax.axhline(y=100, color=INK_MUTED, linestyle=\"--\", linewidth=1.0, alpha=0.7, zorder=1)\n\n# Annotate SPY as benchmark to create visual hierarchy and storytelling focal point\nspy_final = rebased[\"SPY\"][-1]\nspy_color = IMPRINT[3]  # SPY is 4th series (#4467A3)\nax.annotate(\n    \"Benchmark\",\n    xy=(dates[-1], spy_final),\n    xytext=(10, 0),\n    textcoords=\"offset points\",\n    color=spy_color,\n    fontsize=7,\n    fontweight=\"bold\",\n    va=\"center\",\n)\n\n# Date formatting with major monthly ticks and minor biweekly ticks\nax.xaxis.set_major_locator(mdates.MonthLocator())\nax.xaxis.set_major_formatter(mdates.DateFormatter(\"%b '%y\"))\nax.xaxis.set_minor_locator(mdates.WeekdayLocator(byweekday=0, interval=2))\nfig.autofmt_xdate(rotation=30, ha=\"right\")\n\n# Grid — y-axis only, subtle\nax.yaxis.grid(True, alpha=0.15, color=INK, linewidth=0.8)\nax.set_axisbelow(True)\n\n# Spines — L-shaped\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_title(\n    \"line-stock-comparison · python · matplotlib · anyplot.ai\", fontsize=12, fontweight=\"medium\", color=INK, pad=10\n)\nax.set_xlabel(\"Date\", fontsize=10, color=INK)\nax.set_ylabel(\"Rebased Value (Start = 100)\", fontsize=10, color=INK)\nax.tick_params(axis=\"both\", labelsize=8, colors=INK_SOFT)\n\nleg = ax.legend(fontsize=8, loc=\"upper left\", frameon=True)\nif leg:\n    leg.get_frame().set_facecolor(ELEVATED_BG)\n    leg.get_frame().set_edgecolor(INK_SOFT)\n    leg.get_frame().set_linewidth(0.5)\n    plt.setp(leg.get_texts(), color=INK_SOFT)\n\nfig.subplots_adjust(left=0.09, right=0.93, top=0.92, bottom=0.14)\nplt.savefig(f\"plot-{THEME}.png\", dpi=400, facecolor=PAGE_BG)\nplt.close()\n"}