{"spec_id":"box-basic","library":"seaborn","language":"python","code":"\"\"\" anyplot.ai\nbox-basic: Basic Box Plot\nLibrary: seaborn 0.13.2 | Python 3.13.13\nQuality: 90/100 | Updated: 2026-05-28\n\"\"\"\n\nimport os\n\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport pandas as pd\nimport seaborn as sns\n\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\nIMPRINT_PALETTE = [\"#009E73\", \"#C475FD\", \"#4467A3\", \"#BD8233\", \"#AE3030\"]\n\n# Data — daily PM2.5 air quality readings (ug/m3) across 5 city zones\nnp.random.seed(42)\n\nzones_config = [\n    (\"Park\", \"normal\", 8, 3, 90),\n    (\"Residential\", \"normal\", 18, 5, 80),\n    (\"Commercial\", \"normal\", 30, 6, 75),\n    (\"Downtown\", \"bimodal\", None, None, 100),\n    (\"Industrial\", \"exponential\", None, 14, 70),\n]\n\nrecords = []\nfor zone, dist, loc, scale, n in zones_config:\n    if dist == \"bimodal\":\n        values = np.concatenate([np.random.normal(25, 5, n // 2), np.random.normal(44, 6, n // 2)])\n    elif dist == \"exponential\":\n        values = np.random.exponential(scale, n) + 28\n    else:\n        values = np.random.normal(loc, scale, n)\n    values = np.clip(values, 1, None)\n    for v in values:\n        records.append({\"Zone\": zone, \"PM2.5 (ug/m3)\": v})\n\ndf = pd.DataFrame(records)\nzone_order = [\"Park\", \"Residential\", \"Commercial\", \"Downtown\", \"Industrial\"]\n\n# Theme\nsns.set_theme(\n    style=\"ticks\",\n    rc={\n        \"figure.facecolor\": PAGE_BG,\n        \"axes.facecolor\": PAGE_BG,\n        \"axes.edgecolor\": INK_SOFT,\n        \"axes.labelcolor\": INK,\n        \"text.color\": INK,\n        \"xtick.color\": INK_SOFT,\n        \"ytick.color\": INK_SOFT,\n    },\n)\n\n# Plot\nfig, ax = plt.subplots(figsize=(8, 4.5), dpi=400, facecolor=PAGE_BG)\npalette = dict(zip(zone_order, IMPRINT_PALETTE, strict=True))\n\nsns.boxplot(\n    data=df,\n    x=\"Zone\",\n    y=\"PM2.5 (ug/m3)\",\n    hue=\"Zone\",\n    order=zone_order,\n    hue_order=zone_order,\n    palette=palette,\n    linewidth=1.5,\n    fliersize=0,\n    width=0.55,\n    legend=False,\n    ax=ax,\n)\n\nsns.stripplot(\n    data=df,\n    x=\"Zone\",\n    y=\"PM2.5 (ug/m3)\",\n    hue=\"Zone\",\n    order=zone_order,\n    hue_order=zone_order,\n    palette=palette,\n    size=3,\n    alpha=0.25,\n    jitter=0.2,\n    legend=False,\n    ax=ax,\n)\n\n# Style\ntitle = \"box-basic · python · seaborn · anyplot.ai\"\nn_chars = len(title)\nratio = 67 / n_chars if n_chars > 67 else 1.0\ntitle_fontsize = max(8, round(12 * ratio))\n\nax.set_title(title, fontsize=title_fontsize, fontweight=\"medium\", color=INK)\nax.set_xlabel(\"City Zone\", fontsize=10, color=INK)\nax.set_ylabel(\"PM2.5 (ug/m3)\", fontsize=10, color=INK)\nax.tick_params(axis=\"both\", labelsize=8, colors=INK_SOFT)\nax.yaxis.grid(True, alpha=0.15, linewidth=0.8, color=INK)\nsns.despine(ax=ax)\n\nplt.tight_layout()\n\n# Save\nplt.savefig(f\"plot-{THEME}.png\", dpi=400, facecolor=PAGE_BG)\n"}