{"spec_id":"box-horizontal","library":"altair","language":"python","code":"\"\"\" anyplot.ai\nbox-horizontal: Horizontal Box Plot\nLibrary: altair 6.1.0 | Python 3.13.13\nQuality: 86/100 | Updated: 2026-05-12\n\"\"\"\n\nimport os\n\nimport altair as alt\nimport numpy as np\nimport pandas as pd\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\"\n\nBRAND = \"#009E73\"  # Okabe-Ito position 1\n\n# Data - Response times by service type\nnp.random.seed(42)\n\ndata = []\n# Create distributions with different characteristics\ndistributions = {\n    \"Database Query\": (120, 40, 5),  # mean, std, n_outliers\n    \"API Gateway\": (85, 25, 3),\n    \"Authentication\": (45, 15, 2),\n    \"File Storage\": (200, 60, 4),\n    \"Cache Lookup\": (15, 8, 2),\n    \"Email Service\": (150, 50, 3),\n}\n\nfor service, (mean, std, n_outliers) in distributions.items():\n    # Main distribution\n    values = np.random.normal(mean, std, 50)\n    values = np.clip(values, 5, None)  # No negative response times\n    # Add some outliers\n    outliers = np.random.uniform(mean + 3 * std, mean + 5 * std, n_outliers)\n    all_values = np.concatenate([values, outliers])\n    for v in all_values:\n        data.append({\"Service\": service, \"Response Time (ms)\": v})\n\ndf = pd.DataFrame(data)\n\n# Sort by median for easier comparison\nmedians = df.groupby(\"Service\")[\"Response Time (ms)\"].median().sort_values()\ndf[\"Service\"] = pd.Categorical(df[\"Service\"], categories=medians.index, ordered=True)\n\n# Create horizontal box plot\nchart = (\n    alt.Chart(df)\n    .mark_boxplot(\n        box=alt.MarkConfig(color=BRAND),\n        median=alt.MarkConfig(color=INK, size=3),\n        outliers=alt.MarkConfig(color=BRAND, size=80),\n        ticks=alt.MarkConfig(color=BRAND),\n        rule=alt.MarkConfig(color=BRAND),\n    )\n    .encode(\n        x=alt.X(\"Response Time (ms):Q\", title=\"Response Time (ms)\", scale=alt.Scale(zero=False)),\n        y=alt.Y(\"Service:N\", title=\"Service Type\", sort=list(medians.index)),\n        tooltip=[\"Service:N\", \"Response Time (ms):Q\"],\n    )\n    .properties(\n        width=1600,\n        height=900,\n        background=PAGE_BG,\n        title=alt.Title(\"box-horizontal · altair · anyplot.ai\", fontSize=28, anchor=\"middle\"),\n    )\n    .configure_axis(\n        domainColor=INK_SOFT,\n        tickColor=INK_SOFT,\n        gridColor=INK,\n        gridOpacity=0.12,\n        labelColor=INK_SOFT,\n        labelFontSize=18,\n        titleColor=INK,\n        titleFontSize=22,\n        labelLimit=300,\n    )\n    .configure_title(color=INK)\n    .configure_view(strokeWidth=0, fill=PAGE_BG)\n    .interactive()\n)\n\nchart.save(f\"plot-{THEME}.png\", scale_factor=3.0)\nchart.save(f\"plot-{THEME}.html\")\n"}