{"spec_id":"dot-matrix-proportional","library":"plotnine","language":"python","code":"\"\"\" anyplot.ai\ndot-matrix-proportional: Dot Matrix Chart for Proportional Counts\nLibrary: plotnine 0.15.4 | Python 3.13.13\nQuality: 88/100 | Created: 2026-05-08\n\"\"\"\n\nimport os\nimport sys\n\n\n# Prevent this file from shadowing the installed plotnine package\nsys.path = [p for p in sys.path if p != os.path.dirname(os.path.abspath(__file__)) and p != \"\"]\n\nimport pandas as pd\nfrom plotnine import (\n    aes,\n    coord_fixed,\n    element_rect,\n    element_text,\n    geom_point,\n    ggplot,\n    ggsave,\n    labs,\n    scale_color_manual,\n    theme,\n    theme_void,\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\"\n\nIMPRINT = [\"#009E73\", \"#C475FD\", \"#4467A3\"]\n\n# Data – Household Solar Panel Adoption Survey (100 homes, 10×10 grid)\ncategories = [\"Fully Solar-Powered\", \"Partially Solar-Powered\", \"No Solar Panels\"]\ncounts = [24, 41, 35]\ntotal = sum(counts)  # 100\n\ncols = 10\nlabels = []\nfor cat, cnt in zip(categories, counts, strict=True):\n    labels.extend([cat] * cnt)\n\ndf = pd.DataFrame(\n    {\n        \"x\": [i % cols for i in range(total)],\n        \"y\": [-(i // cols) for i in range(total)],\n        \"category\": pd.Categorical(labels, categories=categories),\n    }\n)\n\n# Legend labels include counts\nlegend_labels = [f\"{cat}  ({cnt})\" for cat, cnt in zip(categories, counts, strict=True)]\n\n# Plot\nplot = (\n    ggplot(df, aes(x=\"x\", y=\"y\", color=\"category\"))\n    + geom_point(size=9)\n    + scale_color_manual(values=IMPRINT, labels=legend_labels)\n    + coord_fixed()\n    + labs(\n        title=\"dot-matrix-proportional · plotnine · anyplot.ai\",\n        subtitle=\"Household Solar Panel Adoption Survey  ·  n = 100 homes\",\n        color=\"\",\n    )\n    + theme_void()\n    + theme(\n        plot_background=element_rect(fill=PAGE_BG, color=PAGE_BG),\n        panel_background=element_rect(fill=PAGE_BG),\n        plot_title=element_text(color=INK, size=24, ha=\"left\", weight=\"bold\"),\n        plot_subtitle=element_text(color=INK_SOFT, size=18, ha=\"left\"),\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        legend_key=element_rect(fill=ELEVATED_BG, color=\"None\"),\n        legend_position=\"right\",\n        plot_margin=0.05,\n    )\n)\n\n# Save\nggsave(plot, filename=f\"plot-{THEME}.png\", dpi=300, width=12, height=10)\n"}