{"spec_id":"dot-matrix-proportional","library":"letsplot","language":"python","code":"\"\"\" anyplot.ai\ndot-matrix-proportional: Dot Matrix Chart for Proportional Counts\nLibrary: letsplot 4.9.0 | Python 3.13.13\nQuality: 88/100 | Created: 2026-05-08\n\"\"\"\n\nimport os\n\nimport pandas as pd\nfrom lets_plot import *\nfrom lets_plot import element_blank, element_rect, element_text, theme\nfrom lets_plot.export import ggsave as export_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 — clinical trial side effect profile (n = 100 patients)\ncategories = [\"No Side Effects\", \"Mild Effects\", \"Moderate Effects\", \"Severe Effects\"]\ncounts = [72, 18, 7, 3]\ntotal = sum(counts)  # 100\nCOLS = 10\n\ndot_labels = []\nfor cat, cnt in zip(categories, counts, strict=True):\n    dot_labels.extend([cat] * cnt)\n\nlegend_labels = [f\"{cat}  (n={cnt})\" for cat, cnt in zip(categories, counts, strict=True)]\nlegend_map = dict(zip(categories, legend_labels, strict=True))\n\ndf = pd.DataFrame(\n    {\"col\": [i % COLS for i in range(total)], \"row\": [-(i // COLS) for i in range(total)], \"group\": dot_labels}\n)\ndf[\"legend\"] = pd.Categorical(df[\"group\"].map(legend_map), categories=legend_labels, 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_border=element_blank(),\n    panel_grid_major=element_blank(),\n    panel_grid_minor=element_blank(),\n    axis_title=element_blank(),\n    axis_text=element_blank(),\n    axis_line=element_blank(),\n    axis_ticks=element_blank(),\n    plot_title=element_text(color=INK, size=24),\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_blank(),\n    legend_position=\"right\",\n)\n\nplot = (\n    ggplot(df, aes(x=\"col\", y=\"row\", color=\"legend\"))\n    + geom_point(size=8, alpha=0.95)\n    + scale_color_manual(values=IMPRINT)\n    + labs(title=\"dot-matrix-proportional · letsplot · anyplot.ai\")\n    + theme_void()\n    + ggsize(1200, 1200)\n    + anyplot_theme\n)\n\n# Save\nexport_ggsave(plot, filename=f\"plot-{THEME}.png\", path=\".\", scale=3)\nexport_ggsave(plot, filename=f\"plot-{THEME}.html\", path=\".\")\n"}