{"spec_id":"scatter-regression-polynomial","library":"seaborn","language":"python","code":"\"\"\" anyplot.ai\nscatter-regression-polynomial: Scatter Plot with Polynomial Regression\nLibrary: seaborn 0.13.2 | Python 3.13.14\nQuality: 89/100 | Updated: 2026-08-11\n\"\"\"\n\nimport os\n\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport pandas as pd\nimport seaborn as sns\nfrom matplotlib.lines import Line2D\nfrom matplotlib.patches import Patch\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\nBRAND = \"#009E73\"  # Imprint palette position 1 — first series\nACCENT = \"#C475FD\"  # Imprint palette position 2 — polynomial curve\n\n# Data: Environmental energy efficiency scenario\nnp.random.seed(42)\nn_points = 90\n# Building age (years) vs energy efficiency score\nx = np.linspace(0, 25, n_points)\n# Quadratic relationship: efficiency peaks at ~12 years, then declines\n# y = -0.4x² + 9.6x + 65 + noise (peaks around 80-85 at x≈12, declines to ~45 at x=25)\ny = -0.4 * x**2 + 9.6 * x + 65 + np.random.randn(n_points) * 4\n\n# Prepare data for seaborn\ndf = pd.DataFrame({\"Building Age (years)\": x, \"Energy Efficiency Score\": y})\n\n# Coefficients + R² for the annotation (seaborn's regplot fits internally for\n# the drawn curve/band, but doesn't expose the fitted params — recompute here)\ncoeffs = np.polyfit(x, y, 2)\npoly = np.poly1d(coeffs)\ny_pred = poly(x)\nss_res = np.sum((y - y_pred) ** 2)\nss_tot = np.sum((y - np.mean(y)) ** 2)\nr2 = 1 - (ss_res / ss_tot)\na, b, c = coeffs\n\n# Vertex of the fitted parabola — the \"diminishing returns\" peak the spec calls out\nx_peak = -b / (2 * a)\ny_peak = poly(x_peak)\n\n# Plot setup with theme-adaptive styling\nsns.set_theme(\n    style=\"ticks\",\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        \"legend.facecolor\": ELEVATED_BG,\n        \"legend.edgecolor\": INK_SOFT,\n    },\n)\n\nfig, ax = plt.subplots(figsize=(8, 4.5), dpi=400)\n\n# Distinctive seaborn feature: regplot's built-in polynomial fit (order=2)\n# draws the scatter, the degree-2 curve, and a bootstrapped 95% CI band in\n# a single statistically-aware call, rather than hand-rolling numpy fill_between.\nsns.regplot(\n    data=df,\n    x=\"Building Age (years)\",\n    y=\"Energy Efficiency Score\",\n    order=2,\n    ci=95,\n    ax=ax,\n    scatter_kws={\"s\": 75, \"alpha\": 0.6, \"color\": BRAND, \"edgecolor\": PAGE_BG, \"linewidths\": 0.5},\n    line_kws={\"color\": ACCENT, \"linewidth\": 3},\n)\n\n# regplot doesn't label its artists — build a legend from proxy handles\nlegend_handles = [\n    Line2D(\n        [0],\n        [0],\n        marker=\"o\",\n        color=\"none\",\n        markerfacecolor=BRAND,\n        markeredgecolor=PAGE_BG,\n        markersize=9,\n        alpha=0.6,\n        label=\"Building Data\",\n    ),\n    Line2D([0], [0], color=ACCENT, linewidth=3, label=\"Polynomial Fit (degree 2)\"),\n    Patch(facecolor=ACCENT, alpha=0.35, edgecolor=ACCENT, linewidth=0.8, label=\"95% Confidence Band\"),\n]\nax.legend(\n    handles=legend_handles, fontsize=8, loc=\"upper left\", framealpha=0.9, facecolor=ELEVATED_BG, edgecolor=INK_SOFT\n)\n\n# Callout at the curve's vertex — reinforces the \"diminishing returns\" story\nax.plot([x_peak], [y_peak], marker=\"o\", markersize=7, markerfacecolor=\"none\", markeredgecolor=INK, markeredgewidth=1.5)\nax.annotate(\n    \"Peak efficiency\",\n    xy=(x_peak, y_peak),\n    xytext=(x_peak + 2.5, y_peak - 8),\n    fontsize=8,\n    color=INK_SOFT,\n    arrowprops={\"arrowstyle\": \"-\", \"color\": INK_SOFT, \"linewidth\": 0.8},\n)\n\n# Equation and R² annotation with theme-adaptive box\nsign_b = \"+\" if b >= 0 else \"-\"\nsign_c = \"+\" if c >= 0 else \"-\"\nequation = f\"y = {a:.2f}x² {sign_b} {abs(b):.2f}x {sign_c} {abs(c):.2f}\"\nannotation_text = f\"{equation}\\nR² = {r2:.3f}\"\nax.annotate(\n    annotation_text,\n    xy=(0.97, 0.97),\n    xycoords=\"axes fraction\",\n    fontsize=9,\n    verticalalignment=\"top\",\n    horizontalalignment=\"right\",\n    bbox={\"boxstyle\": \"round,pad=0.6\", \"facecolor\": ELEVATED_BG, \"alpha\": 0.9, \"edgecolor\": INK_SOFT, \"linewidth\": 1},\n)\n\n# Labels and title\nax.set_xlabel(\"Building Age (years)\", fontsize=10, color=INK)\nax.set_ylabel(\"Energy Efficiency Score\", fontsize=10, color=INK)\nax.set_title(\n    \"scatter-regression-polynomial · python · seaborn · anyplot.ai\", fontsize=12, fontweight=\"medium\", color=INK\n)\nax.tick_params(axis=\"both\", labelsize=8, colors=INK_SOFT)\n\n# Grid styling\nax.yaxis.grid(True, alpha=0.15, linewidth=0.8, color=INK)\n\n# Spine visibility (L-shaped default)\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\nplt.tight_layout()\nplt.savefig(f\"plot-{THEME}.png\", dpi=400, facecolor=PAGE_BG)\n"}