diff --git a/plots/bar-grouped/implementations/python/altair.py b/plots/bar-grouped/implementations/python/altair.py index 4d76fa6f19..5575016f36 100644 --- a/plots/bar-grouped/implementations/python/altair.py +++ b/plots/bar-grouped/implementations/python/altair.py @@ -1,13 +1,32 @@ -""" pyplots.ai +""" anyplot.ai bar-grouped: Grouped Bar Chart -Library: altair 6.0.0 | Python 3.13.11 -Quality: 92/100 | Created: 2025-12-24 +Library: altair 6.1.0 | Python 3.13.13 +Quality: 86/100 | Updated: 2026-05-06 """ -import altair as alt +import os +import sys + import pandas as pd +# Remove current directory from path to avoid local altair.py shadowing +script_dir = os.path.dirname(os.path.abspath(__file__)) +sys.path = [p for p in sys.path if p != script_dir and os.path.abspath(p) != script_dir] + +import altair as alt # noqa: E402 + + +# Theme tokens (see prompts/default-style-guide.md "Background" + "Theme-adaptive Chrome") +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 palette (positions 1→3) +OKABE_ITO = ["#009E73", "#D55E00", "#0072B2"] + # Data: Quarterly revenue by product line data = pd.DataFrame( { @@ -35,25 +54,38 @@ alt.Chart(data) .mark_bar(cornerRadiusTopLeft=3, cornerRadiusTopRight=3) .encode( - x=alt.X("Quarter:O", title="Quarter", axis=alt.Axis(labelFontSize=18, titleFontSize=22)), + x=alt.X( + "Quarter:O", + title="Quarter", + axis=alt.Axis(labelFontSize=18, titleFontSize=22, labelColor=INK_SOFT, titleColor=INK), + ), xOffset="Product:N", - y=alt.Y("Revenue:Q", title="Revenue (thousands USD)", axis=alt.Axis(labelFontSize=18, titleFontSize=22)), + y=alt.Y( + "Revenue:Q", + title="Revenue (thousands USD)", + axis=alt.Axis(labelFontSize=18, titleFontSize=22, labelColor=INK_SOFT, titleColor=INK), + ), color=alt.Color( "Product:N", - scale=alt.Scale(domain=["Software", "Hardware", "Services"], range=["#306998", "#FFD43B", "#4ECDC4"]), + scale=alt.Scale(domain=["Software", "Hardware", "Services"], range=OKABE_ITO), legend=alt.Legend( - title="Product Line", titleFontSize=20, labelFontSize=18, orient="top-right", direction="vertical" + title="Product Line", titleFontSize=20, labelFontSize=18, orient="bottom", direction="horizontal" ), ), tooltip=["Quarter", "Product", "Revenue"], ) .properties( - width=1600, height=900, title=alt.Title("bar-grouped · altair · pyplots.ai", fontSize=28, anchor="middle") + width=1600, + height=900, + background=PAGE_BG, + title=alt.Title("bar-grouped · altair · anyplot.ai", fontSize=28, anchor="middle"), ) - .configure_axis(gridColor="#E0E0E0", gridOpacity=0.3) - .configure_view(strokeWidth=0) + .configure_axis(domainColor=INK_SOFT, tickColor=INK_SOFT, gridColor=INK, gridOpacity=0.10) + .configure_view(fill=PAGE_BG, stroke=INK_SOFT, strokeWidth=0) + .configure_title(color=INK) + .configure_legend(fillColor=ELEVATED_BG, strokeColor=INK_SOFT, labelColor=INK_SOFT, titleColor=INK) ) # 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/bar-grouped/metadata/python/altair.yaml b/plots/bar-grouped/metadata/python/altair.yaml index 6a601a3d25..bb564ff454 100644 --- a/plots/bar-grouped/metadata/python/altair.yaml +++ b/plots/bar-grouped/metadata/python/altair.yaml @@ -1,164 +1,211 @@ library: altair +language: python specification_id: bar-grouped created: '2025-12-24T21:28:44Z' -updated: '2025-12-24T21:32:11Z' -generated_by: claude-opus-4-5-20251101 -workflow_run: 20494137794 -issue: 0 -python_version: 3.13.11 -library_version: 6.0.0 -preview_url: https://storage.googleapis.com/anyplot-images/plots/bar-grouped/altair/plot.png -preview_html: https://storage.googleapis.com/anyplot-images/plots/bar-grouped/altair/plot.html -quality_score: 92 -impl_tags: - dependencies: [] - techniques: - - hover-tooltips - - html-export - patterns: [] - dataprep: [] - styling: [] +updated: '2026-05-06T11:10:02Z' +generated_by: claude-haiku +workflow_run: 25431182733 +issue: 1822 +python_version: 3.13.13 +library_version: 6.1.0 +preview_url_light: https://storage.googleapis.com/anyplot-images/plots/bar-grouped/python/altair/plot-light.png +preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/bar-grouped/python/altair/plot-dark.png +preview_html_light: https://storage.googleapis.com/anyplot-images/plots/bar-grouped/python/altair/plot-light.html +preview_html_dark: https://storage.googleapis.com/anyplot-images/plots/bar-grouped/python/altair/plot-dark.html +quality_score: 86 review: strengths: - - Excellent use of Altair declarative xOffset encoding for creating grouped bars - without manual position calculation - - Clean readable code structure following KISS principles - - Colorblind-safe color palette with good visual distinction between product lines - - Appropriate font sizes ensure readability at target resolution - - Tooltips enhance the interactive HTML version - - Realistic business scenario with meaningful quarterly revenue data showing clear - trends + - Perfect technical execution across all core categories (Visual Quality 30/30, + Spec Compliance 15/15, Data Quality 15/15, Code Quality 10/10) + - Excellent theme-adaptive implementation with proper use of INK/INK_SOFT tokens + in both light and dark renders + - Clean, professional grouped bar chart with Okabe-Ito palette correctly applied + (green, orange, blue) + - Proper data selection and realistic quarterly revenue scenario demonstrating product + performance comparison + - Idiomatic altair usage with correct encodings, mark types, and configuration methods + - All text elements properly sized and readable at full resolution in both themes + - Effective use of xOffset for grouped bar positioning with appropriate spacing + and clarity weaknesses: - - Legend placement in top-right overlaps slightly with the plot area; consider orient - right outside the plot - image_description: 'The plot displays a grouped bar chart showing quarterly revenue - by product line. There are 4 quarters (Q1-Q4) on the x-axis, each with 3 side-by-side - bars representing Software (dark blue #306998), Hardware (yellow #FFD43B), and - Services (teal #4ECDC4). The y-axis shows "Revenue (thousands USD)" ranging from - 0 to 180. The title "bar-grouped · altair · pyplots.ai" appears at the top center. - A legend labeled "Product Line" is positioned in the top-right corner. The bars - have subtle rounded corners at the top. Software consistently has the highest - revenue across all quarters (120→145→132→168), Hardware is mid-range (85→78→92→105), - and Services is lowest but growing (45→52→68→75). The grid is very subtle with - low opacity.' + - 'DE-01 and DE-02 could be elevated: consider more sophisticated design elements + like custom typography hierarchy, visual emphasis through color intensity variation, + or layered visual storytelling beyond the default grouped bar structure' + - 'LM-02 (Distinctive Features) is minimal at 2/5: could leverage altair''s interactive + capabilities such as selection, interactive pan/zoom, or brushing to showcase + library-specific strengths' + - 'DE-03 (Data Storytelling) relies on natural structure rather than intentional + emphasis: consider adding color dominance patterns, size variation, or strategic + annotation to guide viewer attention more forcefully' + image_description: |- + Light render (plot-light.png): + Background: Warm off-white #FAF8F1 with subtle grid lines at 10% opacity. Clean, minimal aesthetic. + Chrome: Title "bar-grouped · altair · anyplot.ai" in dark (#1A1A17) at 28px, clearly visible. X-axis label "Quarter" and Y-axis label "Revenue (thousands USD)" in dark text at 22px, fully readable. Tick labels (Q1-Q4, 0-180) at 18px in secondary color (#4A4A44), legible. Legend "Product Line" with colored squares (Software/Hardware/Services) at bottom, dark text on light background. + Data: Three product lines rendered as grouped bars with Okabe-Ito colors: Software=#009E73 (green), Hardware=#D55E00 (orange), Services=#0072B2 (blue). Bars have subtle rounded corners. Spacing between groups is appropriate for visual separation. Data density is ideal (4 quarters × 3 products = 12 bars total). + Legibility verdict: PASS - All text is readable. No text-on-text collisions. Strong contrast between chrome and background. + + Dark render (plot-dark.png): + Background: Warm near-black #1A1A17 with subtle grid lines. Matches light theme aesthetic perfectly. + Chrome: Title in light color (#F0EFE8) at 28px, clearly visible against dark background. Axis labels in light text at 22px, fully readable. Tick labels in lighter secondary color (#B8B7B0) at 18px, legible. Legend maintains dark background with light text, proper contrast. + Data: The three Okabe-Ito colors (#009E73, #D55E00, #0072B2) are IDENTICAL to light render, ensuring brand consistency. Bars are clearly visible and distinguishable from dark background. Rounded corners maintain visual identity. + Legibility verdict: PASS - No dark-on-dark issues. All elements properly adapted for dark theme. Brand green (#009E73) is vibrant and distinct. Both renders are theme-correct. + + Summary: Both renders pass legibility checks. Chrome adapts properly between themes (only background/text colors flip). Data colors remain constant. Professional, readable visualization in both light and dark contexts. criteria_checklist: visual_quality: - score: 37 - max: 40 + score: 30 + max: 30 items: - id: VQ-01 name: Text Legibility - score: 10 - max: 10 + score: 8 + max: 8 passed: true - comment: Title at 28pt, axis labels at 22pt, tick labels at 18pt - all clearly - readable + comment: All text readable at full resolution in both themes. Title 28px, + axis labels 22px, tick labels 18px. Proper use of INK and INK_SOFT tokens + for light/dark themes. - id: VQ-02 name: No Overlap - score: 8 - max: 8 + score: 6 + max: 6 passed: true - comment: No overlapping text elements anywhere + comment: Bars properly spaced with xOffset encoding. No text collisions. Legend + items well-separated. Clear visual hierarchy. - id: VQ-03 name: Element Visibility - score: 8 - max: 8 + score: 6 + max: 6 passed: true - comment: Bars are well-sized with good spacing, xOffset creates clear grouped - separation + comment: All 12 bars (3 products × 4 quarters) clearly visible. Rounded corners + provide subtle definition. Data density appropriate for canvas. - id: VQ-04 name: Color Accessibility - score: 5 - max: 5 + score: 2 + max: 2 passed: true - comment: Blue, yellow, and teal are colorblind-safe (no red-green issues) + comment: Okabe-Ito palette inherently CVD-safe. Adequate contrast in both + themes. Three colors are distinctly differentiable. - id: VQ-05 - name: Layout Balance + name: Layout & Canvas score: 4 - max: 5 + max: 4 passed: true - comment: Good proportions, though legend in top-right slightly overlaps grid - area + comment: Canvas 1600×900 with scale_factor=3.0 = 4800×2700px (correct). Good + proportions. Margins and padding appropriate. No elements cut off. - id: VQ-06 - name: Axis Labels + name: Axis Labels & Title score: 2 max: 2 passed: true - comment: Y-axis has descriptive label with units "Revenue (thousands USD)", - X-axis labeled "Quarter" + comment: 'X-axis: ''Quarter'' (descriptive). Y-axis: ''Revenue (thousands + USD)'' (includes units). Title: ''bar-grouped · altair · anyplot.ai'' (matches + spec format).' - id: VQ-07 - name: Grid & Legend - score: 0 + name: Palette Compliance + score: 2 max: 2 passed: true - comment: Grid is appropriately subtle (alpha 0.3), but legend overlaps the - data area slightly + comment: 'Software=#009E73 (Okabe-Ito pos 1). Hardware=#D55E00 (pos 2). Services=#0072B2 + (pos 3). Plot backgrounds #FAF8F1 (light) and #1A1A17 (dark). No theme-adaptation + failures.' + design_excellence: + score: 10 + max: 20 + items: + - id: DE-01 + name: Aesthetic Sophistication + score: 4 + max: 8 + passed: false + comment: 'Clean professional design but uses default styling patterns. Okabe-Ito + palette (not custom). Rounded bar corners show subtle thought. No dramatic + visual hierarchy or focal point creation. Score: default 4 (could be higher + with custom typography, color intensity variation, or layered visual emphasis).' + - id: DE-02 + name: Visual Refinement + score: 3 + max: 6 + passed: false + comment: 'Grid configured with opacity=0.10 for subtlety. Legend background + uses ELEVATED_BG for separation. Whitespace adequate. Rounded corners show + refinement touch. No spines explicitly removed but design is clean. Score: + 3 (modest customization, not highly refined).' + - id: DE-03 + name: Data Storytelling + score: 3 + max: 6 + passed: false + comment: 'Grouped bar arrangement naturally guides product comparison within + quarters. Ascending revenue pattern visible across Q1-Q4. Color consistency + creates narrative. Software (green) shows clear dominance across all quarters. + No additional visual hierarchy or emphasis techniques applied. Score: 3 + (good natural storytelling from structure, but could be more intentional).' 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 grouped bar chart with side-by-side bars per category - - id: SC-02 - name: Data Mapping score: 5 max: 5 passed: true - comment: Quarter on X, Revenue on Y, Product as grouping variable - - id: SC-03 + comment: Correct grouped bar chart. Uses xOffset encoding for proper side-by-side + positioning. Chart type implementation is accurate. + - id: SC-02 name: Required Features - score: 5 - max: 5 + score: 4 + max: 4 passed: true - comment: Distinct colors, clear legend, consistent bar widths, good spacing - between groups - - id: SC-04 - name: Data Range + comment: 3 product lines displayed side-by-side for each quarter. Clear legend + with product names. Proper axis labels and title. Tooltips enabled for data + exploration. + - id: SC-03 + name: Data Mapping score: 3 max: 3 passed: true - comment: Y-axis shows full range 0-180, all data visible - - id: SC-05 - name: Legend Accuracy - score: 2 - max: 2 - passed: true - comment: Legend correctly labels Software, Hardware, Services - - id: SC-06 - name: Title Format - score: 2 - max: 2 + comment: 'X: Quarter (categorical, ordinal). Y: Revenue (quantitative, 0-180 + range). Color: Product (categorical, Okabe-Ito). All data dimensions properly + mapped.' + - id: SC-04 + name: Title & Legend + score: 3 + max: 3 passed: true - comment: Uses correct format "bar-grouped · altair · pyplots.ai" + comment: 'Title format matches spec: ''bar-grouped · altair · anyplot.ai''. + Legend labeled ''Product Line'' with correct entries. Bottom placement is + standard and readable.' data_quality: - score: 20 - max: 20 + score: 15 + max: 15 items: - id: DQ-01 name: Feature Coverage - score: 8 - max: 8 + score: 6 + max: 6 passed: true - comment: Shows variation across quarters and between products, clear trends - visible + comment: Demonstrates core grouped bar feature with 3 product lines across + 4 quarters. Shows product differentiation and quarterly trends. All expected + chart elements present. - id: DQ-02 name: Realistic Context - score: 7 - max: 7 + score: 5 + max: 5 passed: true - comment: Quarterly revenue by product line is a real business scenario + comment: Business scenario (quarterly revenue by product line) is realistic + and relatable. Revenue values (45-168k USD) are sensible. Product categories + (Software, Hardware, Services) are appropriate. Data relationships are authentic + and neutral. - id: DQ-03 name: Appropriate Scale - score: 5 - max: 5 + score: 4 + max: 4 passed: true - comment: Revenue values 45-168 thousands USD are realistic for product lines + comment: Y-axis range (0-180) is proportional to data spread. No wasted canvas + or excessive compression. Values are well-distributed across the visual + range for clear comparison. code_quality: - score: 7 + score: 10 max: 10 items: - id: CQ-01 @@ -166,42 +213,72 @@ review: score: 3 max: 3 passed: true - comment: Simple imports → data → chart → save structure, no functions/classes + comment: Direct DataFrame creation and chart building. No unnecessary functions + or classes. Straightforward, readable code structure. - id: CQ-02 name: Reproducibility - score: 0 - max: 3 - passed: false - comment: No random data, but data is deterministic (hardcoded) - however, - the code does not use np.random.seed as there's no random data + score: 2 + max: 2 + passed: true + comment: Data is hardcoded deterministically. No randomness or external dependencies. + Output is consistent across runs. - id: CQ-03 name: Clean Imports score: 2 max: 2 passed: true - comment: Only altair and pandas imported, both used + comment: 'Only necessary imports: os, sys, pandas, altair. sys path manipulation + is needed to avoid shadowing. No extraneous imports.' - id: CQ-04 - name: No Deprecated API - score: 1 - max: 1 + name: Code Elegance + score: 2 + max: 2 passed: true - comment: Uses current Altair API + comment: Uses appropriate altair patterns (mark_bar, encode, properties, configure). + No fake interactivity. Theme-adaptive logic is clean and clear. - id: CQ-05 - name: Output Correct + name: Output & API score: 1 max: 1 passed: true - comment: Saves as plot.png and plot.html - library_features: - score: 3 - max: 5 + comment: Correctly saves as f'plot-{THEME}.png' and f'plot-{THEME}.html'. + Uses current Altair 6.1.0 API. scale_factor=3.0 is appropriate. + library_mastery: + score: 6 + max: 10 items: - - id: LF-01 - name: Uses distinctive library features - score: 3 + - id: LM-01 + name: Idiomatic Usage + score: 4 max: 5 - passed: true - comment: Uses xOffset for grouping (Altair-specific), cornerRadius for styling, - tooltips for interactivity, declarative encoding. Could have added selection/interactivity - features. + passed: false + comment: Uses altair's recommended grammar of graphics. Proper mark_bar() + and encoding patterns. xOffset for grouping is idiomatic altair technique. + Proper configuration methods. Missing more advanced interactive patterns + (interactive(), selection()) for full mastery. + - id: LM-02 + name: Distinctive Features + score: 2 + max: 5 + passed: false + comment: Uses basic tooltips and color encoding (standard features). Rounded + corners show attention to detail but are minimal. Could leverage altair's + interactive capabilities (selection, pan/zoom) or more complex encodings + for distinctiveness. + score_caps_applied: [] verdict: APPROVED +impl_tags: + dependencies: + - pandas + techniques: + - grouped-bars + - color-encoding + - tooltips + patterns: + - data-generation + - theme-adaptation + dataprep: [] + styling: + - rounded-corners + - theme-adaptive-chrome + - publication-ready