{"spec_id":"cat-box-strip","library":"letsplot","language":"python","code":"\"\"\" anyplot.ai\ncat-box-strip: Box Plot with Strip Overlay\nLibrary: letsplot 4.9.0 | Python 3.13.13\nQuality: 85/100 | Updated: 2026-05-13\n\"\"\"\n\nimport os\nimport pathlib\n\nimport numpy as np\nimport pandas as pd\nfrom lets_plot import *\n\n\nLetsPlot.setup_html()\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# Okabe-Ito palette\nBOX_COLOR = \"#009E73\"  # Brand green - first series\nPOINT_COLOR = \"#C475FD\"  # Vermillion - second series\n\n# Data - Uptime scores across service tiers\nnp.random.seed(42)\n\ntiers = [\"Basic\", \"Professional\", \"Enterprise\", \"Elite\"]\nn_per_tier = [32, 38, 35, 28]\n\ndata = []\nfor tier, n in zip(tiers, n_per_tier, strict=True):\n    if tier == \"Basic\":\n        # Lower uptime, more variability\n        scores = np.concatenate(\n            [\n                np.random.normal(94.5, 2.5, n - 2),\n                np.array([88.2, 91.5]),  # Some lower outliers\n            ]\n        )\n    elif tier == \"Professional\":\n        # Moderate uptime, consistent\n        scores = np.random.normal(97.8, 1.8, n)\n    elif tier == \"Enterprise\":\n        # High uptime, tight distribution\n        scores = np.concatenate(\n            [\n                np.random.normal(99.2, 0.9, n - 1),\n                np.array([96.5]),  # One lower performer\n            ]\n        )\n    else:  # Elite\n        # Very high uptime, minimal variance\n        scores = np.random.normal(99.7, 0.5, n)\n\n    scores = np.clip(scores, 85, 100)\n    for score in scores:\n        data.append({\"Service Tier\": tier, \"Uptime (%)\": score})\n\ndf = pd.DataFrame(data)\n\n# Custom theme\nanyplot_theme = theme(\n    plot_background=element_rect(fill=PAGE_BG, color=PAGE_BG),\n    panel_background=element_rect(fill=PAGE_BG, color=PAGE_BG),\n    panel_grid_major_y=element_line(color=INK_SOFT, size=0.3),\n    panel_grid_major_x=element_blank(),\n    panel_grid_minor=element_blank(),\n    axis_title=element_text(color=INK, size=20),\n    axis_text=element_text(color=INK_SOFT, size=16),\n    axis_line=element_line(color=INK_SOFT, size=0.5),\n    plot_title=element_text(color=INK, size=24),\n)\n\n# Plot - box plot with jittered strip overlay\nplot = (\n    ggplot(df, aes(x=\"Service Tier\", y=\"Uptime (%)\"))\n    + geom_boxplot(fill=BOX_COLOR, color=INK_SOFT, alpha=0.7, width=0.5, outlier_alpha=0)\n    + geom_jitter(color=POINT_COLOR, size=4, alpha=0.65, width=0.12)\n    + labs(title=\"cat-box-strip · letsplot · anyplot.ai\", x=\"Service Tier\", y=\"Uptime (%)\")\n    + theme_minimal()\n    + anyplot_theme\n    + ggsize(1600, 900)\n)\n\n# Save\noutput_dir = pathlib.Path.cwd()\nggsave(plot, str(output_dir / f\"plot-{THEME}.png\"), scale=3)\nggsave(plot, str(output_dir / f\"plot-{THEME}.html\"))\n"}