{"spec_id":"density-basic","library":"matplotlib","language":"python","code":"\"\"\" anyplot.ai\ndensity-basic: Basic Density Plot\nLibrary: matplotlib 3.10.9 | Python 3.13.13\nQuality: 89/100 | Updated: 2026-05-30\n\"\"\"\n\nimport os\n\nimport matplotlib.pyplot as plt\nimport matplotlib.ticker as ticker\nimport numpy as np\nfrom matplotlib.collections import EventCollection\nfrom matplotlib.colors import LinearSegmentedColormap\nfrom matplotlib.patches import PathPatch\nfrom matplotlib.path import Path\nfrom scipy import stats\nfrom scipy.signal import argrelextrema\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\"  # Imprint palette position 1 — ALWAYS first series\n\n# Data - Response times (ms) showing bimodal server behavior\nnp.random.seed(42)\ncached_responses = np.random.normal(45, 12, 350)  # Fast cache-hit requests\ndb_responses = np.random.normal(140, 25, 150)  # Slower database-query requests\nresponse_times = np.concatenate([cached_responses, db_responses])\nresponse_times = response_times[response_times > 0]\n\n# Compute KDE with Silverman bandwidth selection\nkde = stats.gaussian_kde(response_times, bw_method=\"silverman\")\nx_range = np.linspace(0, response_times.max() + 30, 600)\ndensity = kde(x_range)\n\n# Plot\nfig, ax = plt.subplots(figsize=(8, 4.5), dpi=400, facecolor=PAGE_BG)\nax.set_facecolor(PAGE_BG)\n\n# Imprint sequential gradient fill clipped to density curve via PathPatch\nimprint_seq = LinearSegmentedColormap.from_list(\"imprint_seq\", [BRAND, \"#4467A3\"])\ngradient = np.linspace(0, 1, 256).reshape(-1, 1)\nax.imshow(\n    gradient,\n    extent=[x_range[0], x_range[-1], 0, density.max()],\n    aspect=\"auto\",\n    cmap=imprint_seq,\n    alpha=0.45,\n    origin=\"lower\",\n    zorder=1,\n)\nverts = np.column_stack([np.concatenate([x_range, [x_range[-1], x_range[0]]]), np.concatenate([density, [0, 0]])])\ncodes = [Path.MOVETO] + [Path.LINETO] * (len(verts) - 1)\nclip_path = PathPatch(Path(verts, codes), transform=ax.transData, facecolor=\"none\", edgecolor=\"none\")\nax.add_patch(clip_path)\nfor artist in ax.get_images():\n    artist.set_clip_path(clip_path)\n\n# Density curve\nax.plot(x_range, density, linewidth=2.5, color=BRAND, zorder=3)\n\n# Rug plot via EventCollection — slightly more prominent for full-resolution visibility\nrug = EventCollection(\n    response_times, lineoffset=-0.0006, linelength=0.0013, linewidth=1.1, color=BRAND, alpha=0.55, zorder=2\n)\nax.add_collection(rug)\n\n# Style\ntitle = \"density-basic · python · matplotlib · anyplot.ai\"\ntitle_n = len(title)\ntitle_fontsize = max(8, round(12 * 67 / title_n)) if title_n > 67 else 12\n\nax.set_xlabel(\"Response Time (ms)\", fontsize=10, color=INK)\nax.set_ylabel(\"Density\", fontsize=10, color=INK)\nax.set_title(title, fontsize=title_fontsize, fontweight=\"medium\", color=INK, pad=12)\nax.tick_params(axis=\"both\", labelsize=8, colors=INK_SOFT, length=0)\nax.xaxis.set_major_formatter(ticker.FormatStrFormatter(\"%g\"))\n\n# Grid and spines\nax.yaxis.grid(True, alpha=0.15, linewidth=0.8, color=INK)\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\n# Axis limits — bottom offset accommodates rug plot ticks below zero\nax.set_xlim(x_range[0], x_range[-1])\nax.set_ylim(bottom=-0.0020)\n\n# Suppress the negative y-axis tick label (rug offset lives there, not real density)\nax.yaxis.set_major_formatter(ticker.FuncFormatter(lambda v, _: \"\" if v < 0 else f\"{v:.4g}\"))\n\n# Locate the two KDE peaks and annotate them\npeak_idxs = argrelextrema(density, np.greater, order=25)[0]\nif len(peak_idxs) >= 2:\n    p1_idx, p2_idx = peak_idxs[0], peak_idxs[1]\nelse:\n    # Fallback: split range at midpoint and take each half's argmax\n    mid = len(x_range) // 2\n    p1_idx = np.argmax(density[:mid])\n    p2_idx = mid + np.argmax(density[mid:])\n\np1_x, p1_y = x_range[p1_idx], density[p1_idx]\np2_x, p2_y = x_range[p2_idx], density[p2_idx]\n\nannotation_kw = {\n    \"fontsize\": 8,\n    \"color\": INK_SOFT,\n    \"bbox\": {\"facecolor\": ELEVATED_BG, \"edgecolor\": INK_SOFT, \"alpha\": 0.88, \"boxstyle\": \"round,pad=0.3\"},\n    \"arrowprops\": {\"arrowstyle\": \"->\", \"color\": INK_MUTED, \"lw\": 1.0},\n    \"ha\": \"center\",\n}\nax.annotate(f\"Cache hit\\n~{p1_x:.0f} ms\", xy=(p1_x, p1_y), xytext=(p1_x - 15, p1_y * 0.60), **annotation_kw)\nax.annotate(f\"DB query\\n~{p2_x:.0f} ms\", xy=(p2_x, p2_y), xytext=(p2_x + 22, p2_y * 0.70), **annotation_kw)\n\nplt.tight_layout()\n\n# Save — no bbox_inches='tight' (preserves exact 3200×1800 canvas)\nplt.savefig(f\"plot-{THEME}.png\", dpi=400, facecolor=PAGE_BG)\n"}