{"spec_id":"scatter-categorical","library":"plotnine","language":"python","code":"\"\"\" anyplot.ai\nscatter-categorical: Categorical Scatter Plot\nLibrary: plotnine 0.15.4 | Python 3.13.13\nQuality: 87/100 | Updated: 2026-05-12\n\"\"\"\n\nimport os\nimport pathlib\nimport sys\n\n\n# Remove current directory from path to avoid circular import\ncurrent_dir = str(pathlib.Path(__file__).parent)\nsys.path = [p for p in sys.path if p != current_dir and p != \"\"]\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_point,\n    ggplot,\n    labs,\n    scale_color_manual,\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\"\n\n# Okabe-Ito palette (canonical order)\nIMPRINT = [\"#009E73\", \"#C475FD\", \"#4467A3\"]\n\n# Data\nnp.random.seed(42)\n\n# Create sample data with 3 categories showing different patterns\nn_per_group = 40\n\n# Group A: positive correlation\nx_a = np.random.normal(25, 8, n_per_group)\ny_a = x_a * 0.8 + np.random.normal(10, 4, n_per_group)\n\n# Group B: higher values, positive correlation\nx_b = np.random.normal(45, 10, n_per_group)\ny_b = x_b * 0.6 + np.random.normal(15, 5, n_per_group)\n\n# Group C: lower values, weaker correlation\nx_c = np.random.normal(35, 12, n_per_group)\ny_c = np.random.normal(35, 8, n_per_group)\n\ndf = pd.DataFrame(\n    {\n        \"Temperature (°C)\": np.concatenate([x_a, x_b, x_c]),\n        \"Growth Rate (cm/week)\": np.concatenate([y_a, y_b, y_c]),\n        \"Plant Species\": ([\"Species A\"] * n_per_group + [\"Species B\"] * n_per_group + [\"Species C\"] * n_per_group),\n    }\n)\n\n# Plot\nplot = (\n    ggplot(df, aes(x=\"Temperature (°C)\", y=\"Growth Rate (cm/week)\", color=\"Plant Species\"))\n    + geom_point(size=4, alpha=0.7)\n    + scale_color_manual(values=IMPRINT)\n    + labs(\n        x=\"Temperature (°C)\",\n        y=\"Growth Rate (cm/week)\",\n        title=\"scatter-categorical · plotnine · anyplot.ai\",\n        color=\"Plant Species\",\n    )\n    + theme_minimal()\n    + theme(\n        figure_size=(16, 9),\n        plot_background=element_rect(fill=PAGE_BG, color=PAGE_BG),\n        panel_background=element_rect(fill=PAGE_BG),\n        panel_grid_major=element_line(color=INK, size=0.3, alpha=0.10),\n        panel_grid_minor=element_line(color=INK, size=0.2, alpha=0.05),\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),\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    )\n)\n\n# Save\noutput_dir = pathlib.Path(__file__).parent\nplot.save(str(output_dir / f\"plot-{THEME}.png\"), dpi=300, verbose=False)\n"}