diff --git a/plots/facet-grid/implementations/python/altair.py b/plots/facet-grid/implementations/python/altair.py index 4c55213fab..70ac199235 100644 --- a/plots/facet-grid/implementations/python/altair.py +++ b/plots/facet-grid/implementations/python/altair.py @@ -1,14 +1,25 @@ -""" pyplots.ai +""" anyplot.ai facet-grid: Faceted Grid Plot -Library: altair 6.0.0 | Python 3.13.11 -Quality: 91/100 | Created: 2025-12-30 +Library: altair 6.1.0 | Python 3.13.13 +Quality: 91/100 | Updated: 2026-05-13 """ +import os + import altair as alt import numpy as np import pandas as pd +# Theme tokens +THEME = os.getenv("ANYPLOT_THEME", "light") +PAGE_BG = "#FAF8F1" if THEME == "light" else "#1A1A17" +ELEVATED_BG = "#FFFDF6" if THEME == "light" else "#242420" +INK = "#1A1A17" if THEME == "light" else "#F0EFE8" +INK_SOFT = "#4A4A44" if THEME == "light" else "#B8B7B0" + +OKABE_ITO = ["#009E73", "#D55E00", "#0072B2", "#CC79A7", "#E69F00", "#56B4E9", "#F0E442"] + # Data - Crop yield across different soil types and seasons np.random.seed(42) @@ -21,11 +32,8 @@ for soil in soil_types: for season in seasons: for crop in crop_types: - # Base yield varies by soil type base_yield = {"Sandy": 3.5, "Clay": 4.0, "Loam": 5.0}[soil] - # Season affects yield season_mult = {"Spring": 0.9, "Summer": 1.1, "Fall": 1.0}[season] - # Crop type affects yield and water needs crop_base = {"Wheat": 3.8, "Corn": 4.5, "Soybean": 3.2}[crop] yield_val = np.random.normal(base_yield * season_mult + crop_base, 0.8, n_per_group) @@ -44,31 +52,49 @@ df = pd.DataFrame(data) -# Create faceted chart with scatter plots - facet by soil and season, color by crop +# Create faceted chart with scatter plots chart = ( alt.Chart(df) - .mark_circle(size=100, opacity=0.7) + .mark_circle(size=150, opacity=0.7) .encode( x=alt.X("Water Usage (mm):Q", scale=alt.Scale(zero=False)), y=alt.Y("Yield (tons/ha):Q", scale=alt.Scale(zero=False)), - color=alt.Color("Crop:N", scale=alt.Scale(domain=crop_types, range=["#306998", "#FFD43B", "#4CAF50"])), + color=alt.Color("Crop:N", scale=alt.Scale(domain=crop_types, range=OKABE_ITO[:3])), tooltip=["Yield (tons/ha)", "Water Usage (mm)", "Soil Type", "Season", "Crop"], ) .properties(width=320, height=260) .facet( column=alt.Column( - "Season:N", header=alt.Header(titleFontSize=20, labelFontSize=16), sort=["Spring", "Summer", "Fall"] + "Season:N", header=alt.Header(titleFontSize=22, labelFontSize=18), sort=["Spring", "Summer", "Fall"] ), row=alt.Row( - "Soil Type:N", header=alt.Header(titleFontSize=20, labelFontSize=16), sort=["Sandy", "Clay", "Loam"] + "Soil Type:N", header=alt.Header(titleFontSize=22, labelFontSize=18), sort=["Sandy", "Clay", "Loam"] ), ) - .configure_axis(labelFontSize=14, titleFontSize=16) - .configure_legend(titleFontSize=18, labelFontSize=16, symbolSize=180) - .configure_title(fontSize=24) - .properties(title="facet-grid · altair · pyplots.ai") + .configure_axis( + labelFontSize=16, + titleFontSize=20, + domainColor=INK_SOFT, + tickColor=INK_SOFT, + gridColor=INK, + gridOpacity=0.10, + labelColor=INK_SOFT, + titleColor=INK, + ) + .configure_legend( + titleFontSize=18, + labelFontSize=16, + symbolSize=180, + fillColor=ELEVATED_BG, + strokeColor=INK_SOFT, + labelColor=INK_SOFT, + titleColor=INK, + ) + .configure_title(fontSize=28, color=INK) + .configure_view(fill=PAGE_BG, stroke=INK_SOFT) + .properties(title="facet-grid · altair · anyplot.ai", background=PAGE_BG) ) # Save as PNG and HTML -chart.save("plot.png", scale_factor=3.0) -chart.save("plot.html") +chart.save(f"plot-{THEME}.png", scale_factor=3.0) +chart.save(f"plot-{THEME}.html") diff --git a/plots/facet-grid/metadata/python/altair.yaml b/plots/facet-grid/metadata/python/altair.yaml index 6ce7af77cb..01a119aaad 100644 --- a/plots/facet-grid/metadata/python/altair.yaml +++ b/plots/facet-grid/metadata/python/altair.yaml @@ -1,169 +1,165 @@ library: altair +language: python specification_id: facet-grid created: '2025-12-30T16:30:41Z' -updated: '2025-12-30T16:38:55Z' -generated_by: claude-opus-4-5-20251101 -workflow_run: 20601059244 -issue: 0 -python_version: 3.13.11 -library_version: 6.0.0 -preview_url: https://storage.googleapis.com/anyplot-images/plots/facet-grid/altair/plot.png -preview_html: https://storage.googleapis.com/anyplot-images/plots/facet-grid/altair/plot.html +updated: '2026-05-13T03:36:57Z' +generated_by: claude-haiku +workflow_run: 25776543142 +issue: 2696 +python_version: 3.13.13 +library_version: 6.1.0 +preview_url_light: https://storage.googleapis.com/anyplot-images/plots/facet-grid/python/altair/plot-light.png +preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/facet-grid/python/altair/plot-dark.png +preview_html_light: https://storage.googleapis.com/anyplot-images/plots/facet-grid/python/altair/plot-light.html +preview_html_dark: https://storage.googleapis.com/anyplot-images/plots/facet-grid/python/altair/plot-dark.html quality_score: 91 -impl_tags: - dependencies: [] - techniques: - - faceting - - html-export - patterns: - - data-generation - - iteration-over-groups - dataprep: [] - styling: [] review: strengths: - - Excellent use of Altair's declarative faceting syntax with .facet() for clean - 2D grid creation - - Well-structured agricultural scenario that naturally demonstrates multi-dimensional - data exploration - - Clean color palette (blue, yellow, green) that is both aesthetically pleasing - and colorblind-safe - - Proper use of Altair encoding types (:Q for quantitative, :N for nominal) - - Good axis labels with units and appropriate scale configuration + - 'Perfect visual quality: explicit font sizing, readable in both themes, no overlaps' + - Proper Okabe-Ito palette with correct color ordering; theme-adaptive chrome flips + correctly + - Idiomatic Altair usage with .facet(), .encode(), and configure methods + - Clean code structure and reproducible data generation + - Faceted layout effectively demonstrates the plot type weaknesses: - - Legend is positioned at the edge of the canvas rather than integrated closer to - the plot area - - Could benefit from interactive selections (Altair's distinctive feature) to highlight - crop types across all facets - image_description: 'The plot displays a 3×3 faceted grid of scatter plots showing - crop yield vs water usage. The grid is organized with Season (Spring, Summer, - Fall) as columns and Soil Type (Sandy, Clay, Loam) as rows. Each subplot contains - scatter points colored by crop type: blue for Wheat, yellow for Corn, and green - for Soybean. The title "facet-grid · altair · pyplots.ai" appears at the top left. - Axis labels show "Water Usage (mm)" on x-axis (range ~40-95) and "Yield (tons/ha)" - on y-axis (range ~5-13). A color legend for Crop appears on the right side. The - grid lines are subtle gray, and the overall layout is clean with good spacing - between panels.' + - 'Design Excellence is modest: well-configured defaults but lacks custom aesthetic + sophistication' + - 'Library Mastery could be deeper: doesn''t explore Altair-specific features like + interactive selection' + image_description: |- + Light render (plot-light.png): + Background: Warm off-white surface (#FAF8F1) — correct theme surface + Chrome: Title "facet-grid · altair · anyplot.ai" is prominent and dark. Row headers (Sandy, Clay, Loam) and column headers (Spring, Summer, Fall) are well-sized and easily readable. Axes labeled "Water Usage (mm)" and "Yield (tons/ha)" with units. Tick labels clear. Legend frame with elevated background. + Data: Three colors (teal #009E73, orange #D55E00, blue #0072B2) in Okabe-Ito order. Grid lines subtle (~10% opacity). Scatter markers clearly visible. + Legibility verdict: PASS — all text readable against light background, no legibility issues. + + Dark render (plot-dark.png): + Background: Warm near-black surface (#1A1A17) — correct dark theme surface + Chrome: Title, headers, axis labels, and tick labels all rendered in light tones (INK=#F0EFE8, INK_SOFT=#B8B7B0) and fully readable. Legend frame uses dark elevated background (#242420) with light text. + Data: Colors identical to light render—teal, orange, blue in identical positions. Only chrome differs (background and text colors adapt; data stays the same). + Legibility verdict: PASS — all text readable against dark background, no dark-on-dark failures. Brand green #009E73 visible and clear. criteria_checklist: visual_quality: - score: 36 - max: 40 + score: 30 + max: 30 items: - id: VQ-01 name: Text Legibility - score: 9 - max: 10 + score: 8 + max: 8 passed: true - comment: All text is readable; title, axis labels, and tick marks are appropriately - sized, though axis title font could be slightly larger + comment: All font sizes explicitly set and readable in both themes - id: VQ-02 name: No Overlap - score: 8 - max: 8 + score: 6 + max: 6 passed: true - comment: No overlapping text anywhere in the visualization + comment: No overlapping text elements - id: VQ-03 name: Element Visibility - score: 7 - max: 8 + score: 6 + max: 6 passed: true - comment: Markers are well-sized with good opacity (0.7); slightly crowded - in some cells but still distinguishable + comment: Markers well-adapted to 540-point data density - id: VQ-04 name: Color Accessibility - score: 5 - max: 5 + score: 2 + max: 2 passed: true - comment: Blue, yellow, and green palette is colorblind-safe + comment: CVD-safe Okabe-Ito colors with good contrast - id: VQ-05 - name: Layout Balance + name: Layout & Canvas score: 4 - max: 5 + max: 4 passed: true - comment: Good use of canvas space; the faceted grid fills the area well, though - legend is positioned slightly away from the main plot + comment: Good proportions, balanced margins, legend well-positioned - id: VQ-06 - name: Axis Labels + name: Axis Labels & Title score: 2 max: 2 passed: true - comment: 'Labels include units: "Yield (tons/ha)", "Water Usage (mm)"' + comment: Both axes labeled with units - id: VQ-07 - name: Grid & Legend - score: 1 + name: Palette Compliance + score: 2 max: 2 passed: true - comment: Grid is subtle; legend is clear but positioned at the edge + comment: 'First series #009E73, correct theme chrome, data colors identical + across themes' + design_excellence: + score: 13 + max: 20 + items: + - id: DE-01 + name: Aesthetic Sophistication + score: 4 + max: 8 + passed: false + comment: Well-configured defaults, lacks custom design thought + - id: DE-02 + name: Visual Refinement + score: 5 + max: 6 + passed: true + comment: Subtle grid, explicit sizing, generous whitespace + - id: DE-03 + name: Data Storytelling + score: 4 + max: 6 + passed: false + comment: Faceting creates hierarchy but no explicit visual emphasis spec_compliance: - score: 25 - max: 25 + score: 15 + max: 15 items: - id: SC-01 name: Plot Type - score: 8 - max: 8 - passed: true - comment: Correct faceted grid with scatter plots in each cell - - id: SC-02 - name: Data Mapping score: 5 max: 5 passed: true - comment: X (Water Usage) and Y (Yield) correctly assigned with two categorical - faceting variables - - id: SC-03 + comment: Correct faceted grid with scatter plots + - id: SC-02 name: Required Features - score: 5 - max: 5 + score: 4 + max: 4 passed: true - comment: 'All spec features present: faceting by row (Soil Type) and column - (Season), shared axes, scatter as base plot' - - id: SC-04 - name: Data Range + comment: All spec features present + - id: SC-03 + name: Data Mapping score: 3 max: 3 passed: true - comment: All data visible within axes ranges - - id: SC-05 - name: Legend Accuracy - score: 2 - max: 2 - passed: true - comment: Crop legend correctly shows all three categories - - id: SC-06 - name: Title Format - score: 2 - max: 2 + comment: Axes and encodings correctly assigned + - id: SC-04 + name: Title & Legend + score: 3 + max: 3 passed: true - comment: Correct format "facet-grid · altair · pyplots.ai" + comment: Title format correct, legend labels match data_quality: - score: 18 - max: 20 + score: 15 + max: 15 items: - id: DQ-01 name: Feature Coverage - score: 7 - max: 8 + score: 6 + max: 6 passed: true - comment: Shows variation across soil types (Loam yields higher), seasons (Summer - slightly higher), and crops; demonstrates the multi-dimensional exploration - purpose well + comment: Shows variation across all dimensions - id: DQ-02 name: Realistic Context - score: 7 - max: 7 + score: 5 + max: 5 passed: true - comment: Crop yield vs water usage across soil types and seasons is a realistic - agricultural scenario + comment: Realistic agricultural scenario - id: DQ-03 name: Appropriate Scale score: 4 - max: 5 + max: 4 passed: true - comment: Yield values (5-13 tons/ha) and water usage (40-95 mm) are plausible, - though water usage range is on the lower end for seasonal measurements + comment: Plausible values for domain code_quality: - score: 9 + score: 10 max: 10 items: - id: CQ-01 @@ -171,42 +167,54 @@ review: score: 3 max: 3 passed: true - comment: Clean imports → data → plot → save structure, no functions/classes + comment: Linear structure, no functions/classes - id: CQ-02 name: Reproducibility - score: 3 - max: 3 + score: 2 + max: 2 passed: true - comment: Uses np.random.seed(42) + comment: Seed set to 42 - id: CQ-03 name: Clean Imports score: 2 max: 2 passed: true - comment: All imports are used (altair, numpy, pandas) + comment: Only necessary imports - id: CQ-04 - name: No Deprecated API - score: 1 - max: 1 + name: Code Elegance + score: 2 + max: 2 passed: true - comment: Current Altair API used + comment: Clean, Pythonic, no fake functionality - id: CQ-05 - name: Output Correct - score: 0 + name: Output & API + score: 1 max: 1 - passed: false - comment: Saves as both plot.png and plot.html, which is fine, but minor deduction - for not following the exact single-output convention - library_features: - score: 3 - max: 5 + passed: true + comment: Correct file output format + library_mastery: + score: 8 + max: 10 items: - - id: LF-01 - name: Uses distinctive library features - score: 3 + - id: LM-01 + name: Idiomatic Usage + score: 5 max: 5 passed: true - comment: Good use of Altair's declarative faceting with .facet(), Column/Row - headers, encoding types (:Q, :N), and tooltips. Could leverage more Altair-specific - features like interactive selections or conditional encoding + comment: Uses .facet(), .encode(), configure methods appropriately + - id: LM-02 + name: Distinctive Features + score: 3 + max: 5 + passed: false + comment: Uses faceting but could explore selections or cross-filtering verdict: APPROVED +impl_tags: + dependencies: [] + techniques: + - faceting + - hover-tooltips + patterns: + - data-generation + dataprep: [] + styling: []