{"spec_id":"scatter-categorical","library":"altair","language":"python","code":"\"\"\" anyplot.ai\nscatter-categorical: Categorical Scatter Plot\nLibrary: altair 6.1.0 | Python 3.13.13\nQuality: 90/100 | Updated: 2026-05-12\n\"\"\"\n\nimport os\n\nimport altair as alt\nimport numpy as np\nimport pandas as pd\n\n\n# Theme tokens (see prompts/default-style-guide.md)\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 - Iris-like measurements by species\nnp.random.seed(42)\n\nn_per_species = 50\nspecies_names = [\"Setosa\", \"Versicolor\", \"Virginica\"]\n\ndata = []\nfor i, species in enumerate(species_names):\n    base_petal_length = [1.4, 4.2, 5.5][i]\n    base_petal_width = [0.2, 1.3, 2.0][i]\n    spread = [0.2, 0.5, 0.6][i]\n\n    petal_length = np.random.normal(base_petal_length, spread, n_per_species)\n    petal_width = np.random.normal(base_petal_width, spread * 0.5, n_per_species)\n\n    for pl, pw in zip(petal_length, petal_width, strict=True):\n        data.append({\"Petal Length (cm)\": pl, \"Petal Width (cm)\": pw, \"Species\": species})\n\ndf = pd.DataFrame(data)\n\n# Plot\nchart = (\n    alt.Chart(df)\n    .mark_point(size=200, opacity=0.7, filled=True)\n    .encode(\n        x=alt.X(\"Petal Length (cm):Q\", title=\"Petal Length (cm)\", scale=alt.Scale(zero=False)),\n        y=alt.Y(\"Petal Width (cm):Q\", title=\"Petal Width (cm)\", scale=alt.Scale(zero=False)),\n        color=alt.Color(\n            \"Species:N\",\n            scale=alt.Scale(domain=species_names, range=IMPRINT),\n            legend=alt.Legend(\n                title=\"Species\",\n                titleFontSize=20,\n                labelFontSize=18,\n                symbolSize=200,\n                fillColor=ELEVATED_BG,\n                strokeColor=INK_SOFT,\n            ),\n        ),\n        shape=alt.Shape(\"Species:N\", legend=None),\n        tooltip=[\"Species:N\", \"Petal Length (cm):Q\", \"Petal Width (cm):Q\"],\n    )\n    .properties(\n        width=1600,\n        height=900,\n        background=PAGE_BG,\n        title=alt.Title(\"scatter-categorical · altair · anyplot.ai\", fontSize=28),\n    )\n    .configure_view(fill=PAGE_BG, stroke=INK_SOFT)\n    .configure_axis(\n        domainColor=INK_SOFT,\n        tickColor=INK_SOFT,\n        gridColor=INK,\n        gridOpacity=0.10,\n        labelColor=INK_SOFT,\n        labelFontSize=18,\n        titleColor=INK,\n        titleFontSize=22,\n    )\n    .configure_title(color=INK)\n    .configure_legend(fillColor=ELEVATED_BG, strokeColor=INK_SOFT, labelColor=INK_SOFT, titleColor=INK)\n)\n\n# Save\nchart.save(f\"plot-{THEME}.png\", scale_factor=3.0)\nchart.save(f\"plot-{THEME}.html\")\n"}