{"spec_id":"facet-grid","library":"altair","language":"python","code":"\"\"\" anyplot.ai\nfacet-grid: Faceted Grid Plot\nLibrary: altair 6.1.0 | Python 3.13.13\nQuality: 91/100 | Updated: 2026-05-13\n\"\"\"\n\nimport os\n\nimport altair as alt\nimport numpy as np\nimport pandas as pd\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\", \"#BD8233\", \"#AE3030\", \"#2ABCCD\", \"#954477\"]\n\n# Data - Crop yield across different soil types and seasons\nnp.random.seed(42)\n\nsoil_types = [\"Sandy\", \"Clay\", \"Loam\"]\nseasons = [\"Spring\", \"Summer\", \"Fall\"]\ncrop_types = [\"Wheat\", \"Corn\", \"Soybean\"]\nn_per_group = 20\n\ndata = []\nfor soil in soil_types:\n    for season in seasons:\n        for crop in crop_types:\n            base_yield = {\"Sandy\": 3.5, \"Clay\": 4.0, \"Loam\": 5.0}[soil]\n            season_mult = {\"Spring\": 0.9, \"Summer\": 1.1, \"Fall\": 1.0}[season]\n            crop_base = {\"Wheat\": 3.8, \"Corn\": 4.5, \"Soybean\": 3.2}[crop]\n\n            yield_val = np.random.normal(base_yield * season_mult + crop_base, 0.8, n_per_group)\n            water = np.random.normal(50 + crop_base * 5, 8, n_per_group)\n\n            for y, w in zip(yield_val, water, strict=True):\n                data.append(\n                    {\n                        \"Yield (tons/ha)\": max(0.5, y),\n                        \"Water Usage (mm)\": max(20, w),\n                        \"Soil Type\": soil,\n                        \"Season\": season,\n                        \"Crop\": crop,\n                    }\n                )\n\ndf = pd.DataFrame(data)\n\n# Create faceted chart with scatter plots\nchart = (\n    alt.Chart(df)\n    .mark_circle(size=150, opacity=0.7)\n    .encode(\n        x=alt.X(\"Water Usage (mm):Q\", scale=alt.Scale(zero=False)),\n        y=alt.Y(\"Yield (tons/ha):Q\", scale=alt.Scale(zero=False)),\n        color=alt.Color(\"Crop:N\", scale=alt.Scale(domain=crop_types, range=IMPRINT[:3])),\n        tooltip=[\"Yield (tons/ha)\", \"Water Usage (mm)\", \"Soil Type\", \"Season\", \"Crop\"],\n    )\n    .properties(width=320, height=260)\n    .facet(\n        column=alt.Column(\n            \"Season:N\", header=alt.Header(titleFontSize=22, labelFontSize=18), sort=[\"Spring\", \"Summer\", \"Fall\"]\n        ),\n        row=alt.Row(\n            \"Soil Type:N\", header=alt.Header(titleFontSize=22, labelFontSize=18), sort=[\"Sandy\", \"Clay\", \"Loam\"]\n        ),\n    )\n    .configure_axis(\n        labelFontSize=16,\n        titleFontSize=20,\n        domainColor=INK_SOFT,\n        tickColor=INK_SOFT,\n        gridColor=INK,\n        gridOpacity=0.10,\n        labelColor=INK_SOFT,\n        titleColor=INK,\n    )\n    .configure_legend(\n        titleFontSize=18,\n        labelFontSize=16,\n        symbolSize=180,\n        fillColor=ELEVATED_BG,\n        strokeColor=INK_SOFT,\n        labelColor=INK_SOFT,\n        titleColor=INK,\n    )\n    .configure_title(fontSize=28, color=INK)\n    .configure_view(fill=PAGE_BG, stroke=INK_SOFT)\n    .properties(title=\"facet-grid · altair · anyplot.ai\", background=PAGE_BG)\n)\n\n# Save as PNG and HTML\nchart.save(f\"plot-{THEME}.png\", scale_factor=3.0)\nchart.save(f\"plot-{THEME}.html\")\n"}