{"spec_id":"violin-swarm","library":"plotnine","language":"python","code":"\"\"\" anyplot.ai\nviolin-swarm: Violin Plot with Overlaid Swarm Points\nLibrary: plotnine 0.15.4 | Python 3.13.13\nQuality: 90/100 | Updated: 2026-05-18\n\"\"\"\n\nimport os\n\nimport numpy as np\nimport pandas as pd\nfrom plotnine import (\n    aes,\n    element_line,\n    element_rect,\n    element_text,\n    geom_jitter,\n    geom_violin,\n    ggplot,\n    labs,\n    position_jitter,\n    theme,\n    theme_minimal,\n)\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\"\nBRAND = \"#009E73\"  # Okabe-Ito position 1\nACCENT = \"#C475FD\"  # Okabe-Ito position 2\n\n# Data - Reaction times (ms) across 4 experimental conditions\nnp.random.seed(42)\n\nconditions = [\"Control\", \"Treatment A\", \"Treatment B\", \"Treatment C\"]\nn_per_group = 50\n\ndata = []\nfor condition in conditions:\n    if condition == \"Control\":\n        values = np.random.normal(450, 80, n_per_group)\n    elif condition == \"Treatment A\":\n        values = np.random.normal(380, 60, n_per_group)\n    elif condition == \"Treatment B\":\n        values = np.concatenate(\n            [np.random.normal(420, 40, n_per_group // 2), np.random.normal(520, 50, n_per_group // 2)]\n        )\n    else:  # Treatment C\n        values = np.random.normal(350, 90, n_per_group)\n\n    for v in values:\n        data.append({\"condition\": condition, \"reaction_time\": v})\n\ndf = pd.DataFrame(data)\ndf[\"condition\"] = pd.Categorical(df[\"condition\"], categories=conditions, ordered=True)\n\n# Plot\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=element_line(color=INK_SOFT, size=0.3, alpha=0.12),\n    panel_grid_minor=element_line(color=INK_SOFT, size=0.15, alpha=0.06),\n    panel_border=element_rect(color=INK_SOFT, fill=None, size=0.6),\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, weight=\"medium\"),\n    legend_background=element_rect(fill=ELEVATED_BG, color=INK_SOFT),\n    legend_text=element_text(color=INK_SOFT, size=16),\n    legend_title=element_text(color=INK, size=16),\n    figure_size=(16, 9),\n)\n\nplot = (\n    ggplot(df, aes(x=\"condition\", y=\"reaction_time\"))\n    + geom_violin(fill=BRAND, alpha=0.35, color=BRAND, size=0.8)\n    + geom_jitter(position=position_jitter(width=0.15), color=ACCENT, size=2.5, alpha=0.75, stroke=0.3)\n    + labs(x=\"Experimental Condition\", y=\"Reaction Time (ms)\", title=\"violin-swarm · Python · plotnine · anyplot.ai\")\n    + theme_minimal()\n    + anyplot_theme\n)\n\nplot.save(f\"plot-{THEME}.png\", dpi=300, verbose=False)\n"}