{"spec_id":"violin-grouped-swarm","library":"letsplot","language":"python","code":"\"\"\" anyplot.ai\nviolin-grouped-swarm: Grouped Violin Plot with Swarm Overlay\nLibrary: letsplot 4.9.0 | Python 3.13.13\nQuality: 93/100 | Updated: 2026-05-18\n\"\"\"\n\nimport os\n\nimport numpy as np\nimport pandas as pd\nfrom lets_plot import (\n    LetsPlot,\n    aes,\n    element_blank,\n    element_line,\n    element_rect,\n    element_text,\n    geom_point,\n    geom_violin,\n    ggplot,\n    ggsize,\n    labs,\n    position_dodge,\n    position_jitterdodge,\n    scale_color_manual,\n    scale_fill_manual,\n    theme,\n    theme_minimal,\n)\nfrom lets_plot.export import ggsave\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\nIMPRINT = [\"#009E73\", \"#C475FD\", \"#4467A3\", \"#BD8233\"]\n\n# Data - Drug efficacy across dosage levels and treatment groups\nnp.random.seed(42)\n\ncategories = [\"Low Dose\", \"Medium Dose\", \"High Dose\"]\ngroups = [\"Placebo\", \"Treatment\"]\n\ndata = []\nfor cat in categories:\n    for grp in groups:\n        if cat == \"Low Dose\":\n            base = 3.0 if grp == \"Placebo\" else 4.2\n            spread = 1.2 if grp == \"Placebo\" else 0.8\n        elif cat == \"Medium Dose\":\n            base = 3.5 if grp == \"Placebo\" else 6.1\n            spread = 1.3 if grp == \"Placebo\" else 0.9\n        else:  # High Dose\n            base = 3.8 if grp == \"Placebo\" else 7.5\n            spread = 1.4 if grp == \"Placebo\" else 1.0\n\n        n = 45\n        values = np.random.normal(base, spread, n)\n        values = np.clip(values, 1, 10)\n\n        for v in values:\n            data.append({\"Dosage\": cat, \"Group\": grp, \"Efficacy Score\": v})\n\ndf = pd.DataFrame(data)\n\n# Plot\nplot = (\n    ggplot(df, aes(x=\"Dosage\", y=\"Efficacy Score\", fill=\"Group\", color=\"Group\"))\n    + geom_violin(alpha=0.5, position=position_dodge(width=0.75), size=0.6, trim=False)\n    + geom_point(alpha=0.6, size=2.0, position=position_jitterdodge(jitter_width=0.1, dodge_width=0.75))\n    + scale_fill_manual(values=IMPRINT[:2])\n    + scale_color_manual(values=IMPRINT[:2])\n    + labs(\n        x=\"Dosage Level\",\n        y=\"Efficacy Score\",\n        title=\"violin-grouped-swarm · Python · letsplot · anyplot.ai\",\n        fill=\"Group\",\n        color=\"Group\",\n    )\n    + theme_minimal()\n    + 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.2),\n        panel_grid_minor=element_blank(),\n        axis_title=element_text(size=20, color=INK),\n        axis_text=element_text(size=16, color=INK_SOFT),\n        axis_line=element_line(color=INK_SOFT, size=0.4),\n        plot_title=element_text(size=24, color=INK),\n        legend_background=element_rect(fill=ELEVATED_BG, color=INK_SOFT),\n        legend_text=element_text(size=16, color=INK_SOFT),\n        legend_title=element_text(size=18, color=INK),\n        legend_position=\"right\",\n    )\n    + ggsize(1600, 900)\n)\n\n# Save\nggsave(plot, f\"plot-{THEME}.png\", path=\".\", scale=3)\nggsave(plot, f\"plot-{THEME}.html\", path=\".\")\n"}