{"spec_id":"scatter-regression-lowess","library":"altair","language":"python","code":"\"\"\" anyplot.ai\nscatter-regression-lowess: Scatter Plot with LOWESS Regression\nLibrary: altair 6.1.0 | Python 3.13.13\nQuality: 90/100 | Updated: 2026-05-14\n\"\"\"\n\nimport os\nimport sys\n\nimport numpy as np\nimport pandas as pd\nfrom statsmodels.nonparametric.smoothers_lowess import lowess\n\n\n# Handle module name conflict by removing current directory from import path\noriginal_path = sys.path[:]\nsys.path = [p for p in sys.path if p not in (\"\", \".\")]\nimport altair as alt\n\n\nsys.path = original_path\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\n# Data - complex non-linear relationship\nnp.random.seed(42)\nn = 200\nx = np.linspace(0, 10, n)\n# Non-linear pattern: sine wave with trend and noise\ny = 2 * np.sin(x * 0.8) + 0.5 * x + np.random.normal(0, 0.8, n)\n\n# Create DataFrame for scatter points\ndf = pd.DataFrame({\"x\": x, \"y\": y})\n\n# Compute LOWESS smoothed values\nlowess_result = lowess(y, x, frac=0.3, return_sorted=True)\ndf_lowess = pd.DataFrame({\"x\": lowess_result[:, 0], \"y_lowess\": lowess_result[:, 1]})\n\n# Scatter points layer with filled markers and tooltips\nscatter = (\n    alt.Chart(df)\n    .mark_circle(size=100, opacity=0.6, color=\"#009E73\")\n    .encode(\n        x=alt.X(\"x:Q\", title=\"Independent Variable (meters)\"),\n        y=alt.Y(\"y:Q\", title=\"Dependent Variable (kg)\"),\n        tooltip=[\"x:Q\", \"y:Q\"],\n    )\n)\n\n# LOWESS curve layer\nlowess_line = (\n    alt.Chart(df_lowess).mark_line(strokeWidth=4, color=\"#FFD43B\").encode(x=alt.X(\"x:Q\"), y=alt.Y(\"y_lowess:Q\"))\n)\n\n# Combine layers and apply theme-adaptive styling\nchart = (\n    (scatter + lowess_line)\n    .properties(\n        width=1600,\n        height=900,\n        background=PAGE_BG,\n        title=alt.Title(\"scatter-regression-lowess · altair · anyplot.ai\", fontSize=28),\n    )\n    .configure_axis(\n        domainColor=INK_SOFT,\n        tickColor=INK_SOFT,\n        gridColor=INK,\n        gridOpacity=0.10,\n        labelColor=INK_SOFT,\n        titleColor=INK,\n        labelFontSize=18,\n        titleFontSize=22,\n    )\n    .configure_view(fill=PAGE_BG, stroke=INK_SOFT, strokeWidth=0)\n    .configure_title(color=INK)\n)\n\n# Save with theme-suffixed filenames\nchart.save(f\"plot-{THEME}.png\", scale_factor=3.0)\nchart.save(f\"plot-{THEME}.html\")\n"}