{"spec_id":"violin-grouped-swarm","library":"seaborn","language":"python","code":"\"\"\" anyplot.ai\nviolin-grouped-swarm: Grouped Violin Plot with Swarm Overlay\nLibrary: seaborn 0.13.2 | Python 3.13.13\nQuality: 93/100 | Updated: 2026-05-18\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\"\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\nIMPRINT = [\"#009E73\", \"#C475FD\"]\n\n# Data: Cognitive test performance across different test types and experience levels\nnp.random.seed(42)\n\ntest_types = [\"Reading Comprehension\", \"Arithmetic\", \"Pattern Recognition\"]\nexperience_levels = [\"Novice\", \"Expert\"]\n\ndata = []\nfor test_type in test_types:\n    for exp_level in experience_levels:\n        # Create different distributions based on test type and experience\n        if test_type == \"Reading Comprehension\":\n            base_mean = 72 if exp_level == \"Novice\" else 88\n            base_std = 12 if exp_level == \"Novice\" else 6\n        elif test_type == \"Arithmetic\":\n            base_mean = 65 if exp_level == \"Novice\" else 85\n            base_std = 15 if exp_level == \"Novice\" else 8\n        else:  # Pattern Recognition\n            base_mean = 58 if exp_level == \"Novice\" else 82\n            base_std = 18 if exp_level == \"Novice\" else 10\n\n        scores = np.random.normal(base_mean, base_std, 45)\n        scores = np.clip(scores, 20, 100)  # Keep scores in 0-100 range\n\n        for score in scores:\n            data.append({\"Test Type\": test_type, \"Experience\": exp_level, \"Score\": score})\n\ndf = pd.DataFrame(data)\n\n# Plot\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        \"grid.color\": INK,\n        \"grid.alpha\": 0.10,\n        \"legend.facecolor\": ELEVATED_BG,\n        \"legend.edgecolor\": INK_SOFT,\n    },\n)\n\nfig, ax = plt.subplots(figsize=(16, 9), facecolor=PAGE_BG)\n\n# Violin plot with transparency\nsns.violinplot(\n    data=df, x=\"Test Type\", y=\"Score\", hue=\"Experience\", palette=IMPRINT, alpha=0.5, inner=None, ax=ax, linewidth=2\n)\n\n# Swarm overlay with matching colors and dodging\nsns.swarmplot(\n    data=df,\n    x=\"Test Type\",\n    y=\"Score\",\n    hue=\"Experience\",\n    palette=IMPRINT,\n    dodge=True,\n    size=3.5,\n    alpha=0.7,\n    ax=ax,\n    legend=False,\n)\n\n# Labels and styling\nax.set_xlabel(\"Test Type\", fontsize=20, color=INK)\nax.set_ylabel(\"Score\", fontsize=20, color=INK)\nax.set_title(\"violin-grouped-swarm · Python · seaborn · anyplot.ai\", fontsize=24, fontweight=\"medium\", color=INK)\nax.tick_params(axis=\"both\", labelsize=16, colors=INK_SOFT)\n\n# Remove top and right spines\nax.spines[\"top\"].set_visible(False)\nax.spines[\"right\"].set_visible(False)\nax.spines[\"left\"].set_color(INK_SOFT)\nax.spines[\"bottom\"].set_color(INK_SOFT)\n\n# Subtle grid on y-axis\nax.yaxis.grid(True, alpha=0.10, linewidth=0.8, color=INK)\nax.set_axisbelow(True)\n\n# Legend styling\nax.legend(title=\"Experience\", fontsize=16, title_fontsize=18, loc=\"upper right\")\n\nplt.tight_layout()\nplt.savefig(f\"plot-{THEME}.png\", dpi=300, bbox_inches=\"tight\", facecolor=PAGE_BG)\n"}