{"spec_id":"rug-basic","library":"letsplot","language":"python","code":"\"\"\" anyplot.ai\nrug-basic: Basic Rug Plot\nLibrary: letsplot 4.11.0 | Python 3.13.14\nQuality: 84/100 | Updated: 2026-07-25\n\"\"\"\n\nimport os\n\nimport numpy as np\nimport pandas as pd\nfrom lets_plot import (\n    LetsPlot,\n    aes,\n    element_blank,\n    element_line,\n    element_rect,\n    element_text,\n    geom_density,\n    geom_segment,\n    ggplot,\n    ggsize,\n    labs,\n    theme,\n    theme_minimal,\n)\nfrom lets_plot.export import ggsave\n\n\nLetsPlot.setup_html()\n\n# Theme tokens (Imprint palette)\nTHEME = os.getenv(\"ANYPLOT_THEME\", \"light\")\nPAGE_BG = \"#FAF8F1\" if THEME == \"light\" else \"#1A1A17\"\nINK = \"#1A1A17\" if THEME == \"light\" else \"#F0EFE8\"\nINK_SOFT = \"#4A4A44\" if THEME == \"light\" else \"#B8B7B0\"\nBRAND = \"#009E73\"  # Imprint palette position 1\n\n# Data - simulated response times with clusters and gaps (realistic scenario)\n# Shifted/tightened clusters (80/180/300ms) to diverge from sibling libraries'\n# trimodal placement while keeping the same storytelling shape.\nnp.random.seed(42)\ncluster1 = np.random.normal(80, 10, 45)  # Fast responses ~80ms\ncluster2 = np.random.normal(180, 20, 35)  # Medium responses ~180ms\ncluster3 = np.random.normal(300, 35, 15)  # Slow responses ~300ms\noutliers = np.array([420, 480, 540, 610])  # Edge outliers\nvalues = np.concatenate([cluster1, cluster2, cluster3, outliers])\n\ndf = pd.DataFrame({\"response_time\": values})\n\nrug_y_max = 0.0008\ndf_rug = pd.DataFrame(\n    {\"x\": values, \"xend\": values, \"y\": np.zeros(len(values)), \"yend\": np.full(len(values), rug_y_max)}\n)\n\n# Plot - density curve with rug marks along x-axis\n# lets-plot 4.11.0 has no native geom_rug(); geom_segment is the idiomatic\n# equivalent (a zero-length vertical segment per observation).\nplot = (\n    ggplot(df, aes(x=\"response_time\"))\n    + geom_density(fill=BRAND, alpha=0.25, size=1.5, color=BRAND)\n    + geom_segment(aes(x=\"x\", xend=\"xend\", y=\"y\", yend=\"yend\"), data=df_rug, color=BRAND, alpha=0.55, size=1.0)\n    + labs(x=\"Response Time (ms)\", y=\"Density\", title=\"rug-basic · python · letsplot · anyplot.ai\")\n    + theme_minimal()\n    + theme(\n        plot_background=element_rect(fill=PAGE_BG, color=PAGE_BG),\n        panel_background=element_rect(fill=PAGE_BG),\n        panel_border=element_blank(),\n        axis_title=element_text(size=20, color=INK),\n        axis_text=element_text(size=16, color=INK_SOFT),\n        plot_title=element_text(size=24, color=INK),\n        panel_grid_major_y=element_line(color=INK_SOFT, size=0.2),\n        panel_grid_major_x=element_blank(),\n        panel_grid_minor=element_blank(),\n        axis_line=element_line(color=INK_SOFT),\n    )\n    + ggsize(800, 450)\n)\n\n# Save PNG (scale 4x for 3200x1800) and HTML\nggsave(plot, f\"plot-{THEME}.png\", path=\".\", scale=4)\nggsave(plot, f\"plot-{THEME}.html\", path=\".\")\n"}