{"spec_id":"strip-basic","library":"letsplot","language":"python","code":"\"\"\" anyplot.ai\nstrip-basic: Basic Strip Plot\nLibrary: letsplot 4.11.0 | Python 3.13.14\nQuality: 90/100 | Updated: 2026-08-05\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_jitter,\n    ggplot,\n    ggsave,\n    ggsize,\n    labs,\n    scale_color_manual,\n    stat_summary,\n    theme,\n    theme_minimal,\n)\n\n\nLetsPlot.setup_html()\n\n# Theme tokens\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\"\n\n# Imprint categorical palette - position 1 is always #009E73\nIMPRINT_PALETTE = [\"#009E73\", \"#C475FD\", \"#4467A3\", \"#BD8233\"]\n\n# Data - Survey response scores by department\nnp.random.seed(42)\n\ndepartments = [\"Marketing\", \"Engineering\", \"Sales\", \"Support\"]\ndata = []\n\ndistributions = {\"Marketing\": (72, 12), \"Engineering\": (78, 8), \"Sales\": (68, 15), \"Support\": (75, 10)}\n\nfor dept in departments:\n    n_points = np.random.randint(25, 45)\n    mean, std = distributions[dept]\n    scores = np.clip(np.random.normal(mean, std, n_points), 40, 100)\n    for score in scores:\n        data.append({\"Department\": dept, \"Score\": score})\n\ndf = pd.DataFrame(data)\n\n# Plot - individual points per department, jittered to reveal every observation\nplot = (\n    ggplot(df, aes(x=\"Department\", y=\"Score\"))\n    + geom_jitter(aes(color=\"Department\"), size=4, alpha=0.65, width=0.25, height=0, seed=42, show_legend=False)\n    # Mean + interquartile reference per department - draws the eye to the\n    # Engineering-vs-Sales spread/level contrast that the raw jitter alone hides\n    + stat_summary(\n        aes(x=\"Department\", y=\"Score\"), fun=\"mean\", fun_min=\"lq\", fun_max=\"uq\", geom=\"pointrange\", color=INK, size=1.1\n    )\n    + scale_color_manual(values=IMPRINT_PALETTE)\n    + labs(x=\"Department\", y=\"Survey Score (points)\", title=\"strip-basic · python · letsplot · anyplot.ai\")\n    + ggsize(800, 450)\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        axis_title=element_text(color=INK, size=12),\n        axis_text=element_text(color=INK_SOFT, size=10),\n        plot_title=element_text(color=INK, size=16),\n        panel_grid_major_x=element_blank(),\n        panel_grid_minor=element_blank(),\n        panel_grid_major_y=element_line(color=INK_SOFT, size=0.3),\n        panel_border=element_blank(),\n        axis_line=element_line(color=INK_SOFT, size=0.5),\n    )\n)\n\n# Save\nggsave(plot, f\"plot-{THEME}.png\", path=\".\", scale=4)\nggsave(plot, f\"plot-{THEME}.html\", path=\".\")\n"}