{"spec_id":"density-basic","library":"plotly","language":"python","code":"\"\"\" anyplot.ai\ndensity-basic: Basic Density Plot\nLibrary: plotly 6.7.0 | Python 3.13.13\nQuality: 92/100 | Updated: 2026-05-30\n\"\"\"\n\nimport os\nimport sys\n\n\n# Remove the script's own directory from sys.path to avoid shadowing the plotly package\nsys.path = [p for p in sys.path if os.path.abspath(p) != os.path.dirname(os.path.abspath(__file__))]\n\nimport numpy as np\nimport plotly.graph_objects as go\nfrom scipy.stats import gaussian_kde\n\n\nTHEME = os.getenv(\"ANYPLOT_THEME\", \"light\")\n\n# Theme-adaptive chrome tokens (see default-style-guide.md)\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\"\nGRID = \"rgba(26,26,23,0.15)\" if THEME == \"light\" else \"rgba(240,239,232,0.15)\"\n\n# Imprint palette — first series is always #009E73\nBRAND = \"#009E73\"\nFILL = \"rgba(0,158,115,0.2)\"\n\n# Data — SAT Math scores with bimodal distribution\nnp.random.seed(42)\nsat_scores = np.concatenate(\n    [\n        np.random.normal(540, 60, 350),  # main group\n        np.random.normal(680, 35, 150),  # high achievers\n    ]\n)\nsat_scores = np.clip(sat_scores, 200, 800)\n\n# KDE via scipy\nkde = gaussian_kde(sat_scores)\nx_grid = np.linspace(350, 800, 500)\ndensity = kde(x_grid)\n\n# Locate the two peaks (valley near 620)\nsplit = int(500 * (620 - 350) / (800 - 350))\npeak1_idx = np.argmax(density[:split])\npeak2_idx = split + np.argmax(density[split:])\npeak1_x, peak1_y = x_grid[peak1_idx], density[peak1_idx]\npeak2_x, peak2_y = x_grid[peak2_idx], density[peak2_idx]\n\nfig = go.Figure()\n\n# KDE curve with filled area\nfig.add_trace(\n    go.Scatter(\n        x=x_grid,\n        y=density,\n        mode=\"lines\",\n        fill=\"tozeroy\",\n        fillcolor=FILL,\n        line={\"color\": BRAND, \"width\": 2.5},\n        name=\"Density\",\n        hovertemplate=\"Score: %{x:.0f}<br>Density: %{y:.4f}<extra></extra>\",\n    )\n)\n\n# Rug plot — individual observations as tick marks along x-axis\nfig.add_trace(\n    go.Scatter(\n        x=sat_scores,\n        y=np.zeros(len(sat_scores)),\n        mode=\"markers\",\n        marker={\"symbol\": \"line-ns\", \"size\": 10, \"color\": INK_SOFT, \"opacity\": 0.5, \"line\": {\"width\": 1}},\n        name=\"Observations\",\n        hovertemplate=\"Score: %{x:.0f}<extra></extra>\",\n    )\n)\n\n# Peak annotations highlighting the bimodal structure\nfor label, px, py, ax, ay in [\n    (f\"<b>Primary Peak</b><br>~{peak1_x:.0f} pts\", peak1_x, peak1_y, -80, -50),\n    (f\"<b>High Achievers</b><br>~{peak2_x:.0f} pts\", peak2_x, peak2_y, 80, -40),\n]:\n    fig.add_annotation(\n        x=px,\n        y=py,\n        text=label,\n        showarrow=True,\n        arrowhead=2,\n        arrowsize=1.2,\n        arrowwidth=1.5,\n        arrowcolor=BRAND,\n        font={\"size\": 10, \"color\": INK},\n        ax=ax,\n        ay=ay,\n        bgcolor=ELEVATED_BG,\n        borderpad=4,\n        borderwidth=0,\n    )\n\nfig.update_layout(\n    autosize=False,\n    title={\n        \"text\": \"density-basic · python · plotly · anyplot.ai\",\n        \"font\": {\"size\": 16, \"color\": INK},\n        \"x\": 0.5,\n        \"xanchor\": \"center\",\n    },\n    xaxis={\n        \"title\": {\"text\": \"SAT Math Score (points)\", \"font\": {\"size\": 12, \"color\": INK}},\n        \"tickfont\": {\"size\": 10, \"color\": INK_SOFT},\n        \"showgrid\": False,\n        \"zeroline\": False,\n        \"linecolor\": INK_SOFT,\n        \"showspikes\": True,\n        \"spikemode\": \"across\",\n        \"spikethickness\": 1,\n        \"spikecolor\": \"rgba(0,158,115,0.3)\",\n        \"spikedash\": \"dot\",\n    },\n    yaxis={\n        \"title\": {\"text\": \"Density\", \"font\": {\"size\": 12, \"color\": INK}},\n        \"tickfont\": {\"size\": 10, \"color\": INK_SOFT},\n        \"gridcolor\": GRID,\n        \"gridwidth\": 1,\n        \"linecolor\": INK_SOFT,\n        \"zeroline\": False,\n        \"rangemode\": \"tozero\",\n    },\n    paper_bgcolor=PAGE_BG,\n    plot_bgcolor=PAGE_BG,\n    font={\"color\": INK},\n    showlegend=False,\n    hovermode=\"x\",\n    margin={\"l\": 80, \"r\": 40, \"t\": 80, \"b\": 60},\n)\n\nfig.write_image(f\"plot-{THEME}.png\", width=800, height=450, scale=4)\nfig.write_html(f\"plot-{THEME}.html\", include_plotlyjs=\"cdn\", config={\"displayModeBar\": True, \"scrollZoom\": True})\n"}