{"spec_id":"area-basic","library":"seaborn","language":"python","code":"\"\"\" anyplot.ai\narea-basic: Basic Area Chart\nLibrary: seaborn 0.13.2 | Python 3.13.13\nQuality: 90/100 | Updated: 2026-05-28\n\"\"\"\n\nimport os\n\nimport matplotlib.dates as mdates\nimport matplotlib.pyplot as plt\nimport matplotlib.ticker as mticker\nimport numpy as np\nimport pandas as pd\nimport seaborn as sns\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\"\nINK_MUTED = \"#6B6A63\" if THEME == \"light\" else \"#A8A79F\"\nBRAND = \"#009E73\"\n\n# Data - daily website visitors over a month\nnp.random.seed(42)\ndates = pd.date_range(start=\"2024-03-01\", periods=30, freq=\"D\")\nbase_visitors = 8000\ntrend = np.linspace(0, 2000, 30)\nweekly_pattern = np.array([1.0, 1.1, 1.15, 1.2, 1.1, 0.7, 0.65] * 5)[:30]\nnoise = np.random.randn(30) * 350\nvisitors = (base_visitors + trend) * weekly_pattern + noise\nvisitors[9:12] *= 0.22  # Planned maintenance window (days 10–12)\nvisitors = np.maximum(visitors, 100)\n\ndf = pd.DataFrame({\"date\": dates, \"visitors\": visitors})\navg_visitors = df[\"visitors\"].mean()\ny_max = df[\"visitors\"].max() * 1.18\n\n# Configure seaborn theme (theme-adaptive chrome)\nsns.set_theme(\n    style=\"white\",\n    rc={\n        \"figure.facecolor\": PAGE_BG,\n        \"axes.facecolor\": PAGE_BG,\n        \"axes.edgecolor\": INK_SOFT,\n        \"axes.labelcolor\": INK,\n        \"text.color\": INK,\n        \"xtick.color\": INK_SOFT,\n        \"ytick.color\": INK_SOFT,\n        \"grid.color\": INK,\n        \"grid.alpha\": 0.15,\n        \"axes.spines.top\": False,\n        \"axes.spines.right\": False,\n    },\n)\n\nfig, ax = plt.subplots(figsize=(8, 4.5), dpi=400, facecolor=PAGE_BG)\nax.set_facecolor(PAGE_BG)\n\n# Layered gradient fill using seaborn's light_palette — 3 layers at higher alpha\n# for stronger area visual weight than the previous 5-layer faint approach\npalette_colors = sns.light_palette(BRAND, n_colors=5)\nfor i in range(3):\n    frac = (i + 1) / 3\n    ax.fill_between(df[\"date\"], 0, df[\"visitors\"] * frac, color=palette_colors[i + 2], alpha=0.28, linewidth=0)\n\n# Seaborn lineplot for the area boundary line\nsns.lineplot(data=df, x=\"date\", y=\"visitors\", ax=ax, color=BRAND, linewidth=2.5)\n\n# Annotate the scheduled maintenance dip (days 10–12)\nmaint_idx = 10\nmaint_val = df[\"visitors\"].iloc[maint_idx]\nax.annotate(\n    \"Scheduled\\nmaintenance\",\n    xy=(df[\"date\"].iloc[maint_idx], maint_val + 80),\n    xytext=(df[\"date\"].iloc[maint_idx + 6], maint_val + 4200),\n    fontsize=8,\n    fontweight=\"semibold\",\n    color=INK,\n    arrowprops={\"arrowstyle\": \"->\", \"color\": INK_SOFT, \"lw\": 1.2, \"connectionstyle\": \"arc3,rad=0.2\"},\n    ha=\"center\",\n    va=\"bottom\",\n)\n\n# Monthly average reference line\nax.axhline(y=avg_visitors, color=INK_SOFT, linestyle=\"--\", linewidth=1.0, alpha=0.6, zorder=1)\nax.text(\n    df[\"date\"].iloc[-1],\n    avg_visitors + y_max * 0.012,\n    f\"Avg: {avg_visitors:,.0f}\",\n    fontsize=8,\n    color=INK_MUTED,\n    ha=\"right\",\n    va=\"bottom\",\n    fontstyle=\"italic\",\n)\n\n# Labels and title\ntitle = \"area-basic · python · seaborn · anyplot.ai\"\nn = len(title)\nratio = 67 / n if n > 67 else 1.0\ntitle_fontsize = max(8, round(12 * ratio))\n\nax.set_xlabel(\"Date\", fontsize=10, color=INK)\nax.set_ylabel(\"Visitors / day\", fontsize=10, color=INK)\nax.set_title(title, fontsize=title_fontsize, fontweight=\"medium\", color=INK, pad=8)\nax.tick_params(axis=\"both\", labelsize=8, colors=INK_SOFT)\n\n# Spine, grid, and axes styling\nsns.despine(ax=ax)\nax.yaxis.grid(True, alpha=0.15, linewidth=0.8, color=INK)\nax.set_axisbelow(True)\nax.yaxis.set_major_formatter(mticker.FuncFormatter(lambda x, _: f\"{x:,.0f}\"))\nax.xaxis.set_major_locator(mdates.WeekdayLocator(byweekday=mdates.MO))\nax.xaxis.set_minor_locator(mdates.DayLocator())\nax.xaxis.set_major_formatter(mdates.DateFormatter(\"%b %d\"))\nplt.setp(ax.get_xticklabels(), rotation=30, ha=\"right\")\nax.set_ylim(bottom=0, top=y_max)\n\nplt.tight_layout()\nplt.savefig(f\"plot-{THEME}.png\", dpi=400, facecolor=PAGE_BG)\n"}