diff --git a/plots/bar-grouped/implementations/python/highcharts.py b/plots/bar-grouped/implementations/python/highcharts.py index 01a836d3ea..0134cbc1cb 100644 --- a/plots/bar-grouped/implementations/python/highcharts.py +++ b/plots/bar-grouped/implementations/python/highcharts.py @@ -1,9 +1,10 @@ -""" pyplots.ai +""" anyplot.ai bar-grouped: Grouped Bar Chart -Library: highcharts unknown | Python 3.13.11 -Quality: 91/100 | Created: 2025-12-24 +Library: highcharts unknown | Python 3.13.13 +Quality: 87/100 | Updated: 2026-05-06 """ +import os import tempfile import time import urllib.request @@ -16,6 +17,17 @@ from selenium.webdriver.chrome.options import Options +# Theme-adaptive colors +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" +GRID = "rgba(26,26,23,0.10)" if THEME == "light" else "rgba(240,239,232,0.10)" + +# Okabe-Ito palette - first series is always #009E73 +OKABE_ITO = ["#009E73", "#D55E00", "#0072B2", "#CC79A7", "#E69F00", "#56B4E9", "#F0E442"] + # Data - Quarterly revenue by product line (realistic business scenario) categories = ["Q1", "Q2", "Q3", "Q4"] products = { @@ -24,9 +36,6 @@ "Home & Garden": [156, 178, 195, 224], } -# Colors - Python Blue first, then colorblind-safe palette -colors = ["#306998", "#FFD43B", "#9467BD"] - # Create chart with container specified chart = Chart(container="container") chart.options = HighchartsOptions() @@ -36,40 +45,41 @@ "type": "column", "width": 4800, "height": 2700, - "backgroundColor": "#ffffff", + "backgroundColor": PAGE_BG, "marginBottom": 280, - "style": {"fontFamily": "Arial, sans-serif"}, + "style": {"fontFamily": "Arial, sans-serif", "color": INK}, } # Title chart.options.title = { - "text": "bar-grouped · highcharts · pyplots.ai", - "style": {"fontSize": "72px", "fontWeight": "bold"}, + "text": "bar-grouped · highcharts · anyplot.ai", + "style": {"fontSize": "28px", "color": INK, "fontWeight": "bold"}, } # Subtitle for context chart.options.subtitle = { "text": "Quarterly Revenue by Product Line (in thousands USD)", - "style": {"fontSize": "42px", "color": "#666666"}, + "style": {"fontSize": "22px", "color": INK_SOFT}, } # X-axis configuration chart.options.x_axis = { "categories": categories, - "title": {"text": "Quarter", "style": {"fontSize": "48px", "fontWeight": "bold"}}, - "labels": {"style": {"fontSize": "36px"}}, - "lineWidth": 2, - "tickWidth": 2, + "title": {"text": "Quarter", "style": {"fontSize": "22px", "color": INK, "fontWeight": "bold"}}, + "labels": {"style": {"fontSize": "18px", "color": INK_SOFT}}, + "lineColor": INK_SOFT, + "tickColor": INK_SOFT, + "gridLineColor": GRID, } # Y-axis configuration chart.options.y_axis = { "min": 0, - "title": {"text": "Revenue (thousands USD)", "style": {"fontSize": "48px", "fontWeight": "bold"}}, - "labels": {"style": {"fontSize": "36px"}, "format": "${value}K"}, - "gridLineWidth": 1, - "gridLineDashStyle": "Dash", - "gridLineColor": "#cccccc", + "title": {"text": "Revenue (thousands USD)", "style": {"fontSize": "22px", "color": INK, "fontWeight": "bold"}}, + "labels": {"style": {"fontSize": "18px", "color": INK_SOFT}, "format": "${value}K"}, + "lineColor": INK_SOFT, + "tickColor": INK_SOFT, + "gridLineColor": GRID, } # Legend configuration @@ -81,15 +91,15 @@ "x": -50, "y": 100, "floating": True, - "backgroundColor": "#ffffff", + "backgroundColor": ELEVATED_BG, "borderWidth": 1, - "borderColor": "#cccccc", - "shadow": True, - "itemStyle": {"fontSize": "36px", "fontWeight": "normal"}, - "symbolHeight": 24, - "symbolWidth": 40, + "borderColor": INK_SOFT, + "shadow": False, + "itemStyle": {"fontSize": "18px", "color": INK_SOFT, "fontWeight": "normal"}, + "symbolHeight": 16, + "symbolWidth": 24, "symbolRadius": 4, - "itemMarginBottom": 10, + "itemMarginBottom": 8, } # Plot options for grouped bars @@ -98,11 +108,11 @@ "groupPadding": 0.15, "pointPadding": 0.05, "borderWidth": 2, - "borderColor": "#ffffff", + "borderColor": PAGE_BG, "dataLabels": { "enabled": True, "format": "${y}K", - "style": {"fontSize": "28px", "fontWeight": "bold", "textOutline": "2px white"}, + "style": {"fontSize": "16px", "fontWeight": "bold", "color": INK}, }, } } @@ -112,7 +122,7 @@ series = ColumnSeries() series.name = product_name series.data = values - series.color = colors[i] + series.color = OKABE_ITO[i] chart.add_series(series) # Download Highcharts JS for inline embedding (required for headless Chrome) @@ -128,7 +138,7 @@ -
+ @@ -140,7 +150,7 @@ temp_path = f.name # Save interactive HTML version -with open("plot.html", "w", encoding="utf-8") as f: +with open(f"plot-{THEME}.html", "w", encoding="utf-8") as f: f.write(html_content) # Set up headless Chrome for PNG export @@ -155,7 +165,7 @@ driver = webdriver.Chrome(options=chrome_options) driver.get(f"file://{temp_path}") time.sleep(5) # Wait for chart to render -driver.save_screenshot("plot.png") +driver.save_screenshot(f"plot-{THEME}.png") driver.quit() # Clean up temp file diff --git a/plots/bar-grouped/metadata/python/highcharts.yaml b/plots/bar-grouped/metadata/python/highcharts.yaml index 5197fe1971..f428290a28 100644 --- a/plots/bar-grouped/metadata/python/highcharts.yaml +++ b/plots/bar-grouped/metadata/python/highcharts.yaml @@ -1,167 +1,174 @@ library: highcharts +language: python specification_id: bar-grouped created: '2025-12-24T21:30:39Z' -updated: '2025-12-24T21:40:33Z' -generated_by: claude-opus-4-5-20251101 -workflow_run: 20494139008 -issue: 0 -python_version: 3.13.11 +updated: '2026-05-06T11:16:17Z' +generated_by: claude-haiku +workflow_run: 25431456709 +issue: 1822 +python_version: 3.13.13 library_version: unknown -preview_url: https://storage.googleapis.com/anyplot-images/plots/bar-grouped/highcharts/plot.png -preview_html: https://storage.googleapis.com/anyplot-images/plots/bar-grouped/highcharts/plot.html -quality_score: 91 -impl_tags: - dependencies: - - selenium - techniques: - - html-export - patterns: - - explicit-figure - dataprep: [] - styling: [] +preview_url_light: https://storage.googleapis.com/anyplot-images/plots/bar-grouped/python/highcharts/plot-light.png +preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/bar-grouped/python/highcharts/plot-dark.png +preview_html_light: https://storage.googleapis.com/anyplot-images/plots/bar-grouped/python/highcharts/plot-light.html +preview_html_dark: https://storage.googleapis.com/anyplot-images/plots/bar-grouped/python/highcharts/plot-dark.html +quality_score: 87 review: strengths: - - Excellent title formatting following the spec-id · library · pyplots.ai convention - - Professional colorblind-safe palette (Python Blue, Yellow, Purple) - - 'Good use of Highcharts features: data labels, styled legend with border/shadow, - dashed grid lines' - - Appropriate 4800x2700 sizing with properly scaled font sizes - - Clean code structure following the library-specific export pattern with inline - JS - - Realistic business scenario with meaningful data context + - 'Critical repair complete: all attempt-1 failures resolved (dark mode readable, + palette correct, theme-adaptive architecture, output filenames)' + - Theme-adaptive excellence with proper contrast and readability in both light and + dark renders + - Okabe-Ito palette compliance with correct color positions and theme-independent + data colors + - Professional, clean code structure with proper selenium integration and correct + file outputs + - Realistic business data scenario with clear quarterly and product comparisons weaknesses: - - Y-axis has too many tick intervals (every $10K from 0 to $420K creates 43 tick - marks), making the grid overly dense - - All three product lines show uniform upward trends - data could demonstrate more - varied patterns (e.g., one declining, seasonal variations) - image_description: 'The plot displays a grouped bar chart with 4 quarters (Q1, Q2, - Q3, Q4) on the x-axis and revenue values on the y-axis. Three product lines are - shown as grouped vertical bars: Electronics (blue #306998), Clothing (yellow #FFD43B), - and Home & Garden (purple #9467BD). The title "bar-grouped · highcharts · pyplots.ai" - appears prominently at the top with a subtitle "Quarterly Revenue by Product Line - (in thousands USD)". Each bar has data labels showing values (e.g., $245K, $312K, - $287K, $398K for Electronics). The y-axis displays "Revenue (thousands USD)" with - formatted tick labels ($0K to $420K in $10K increments), and the x-axis shows - "Quarter". A boxed legend with the three product lines is positioned in the top-right - corner with a subtle border and shadow.' + - 'Limited design sophistication: uses library defaults without custom visual enhancements' + - 'No distinctive highcharts features: lacks interactive tooltips, animations, or + advanced formatting' + - No visual emphasis or focal point techniques to guide viewer attention + image_description: |- + Light render (plot-light.png): + Background: Warm off-white #FAF8F1 (correct) + Chrome: Title, subtitle, and axis labels all in dark INK color with clear readability + Data: Green (#009E73), Orange (#D55E00), Blue (#0072B2) - correct Okabe-Ito positions 1-3 + Data labels visible on each bar (e.g., "245K", "312K", etc.) + Legend: Floating right-aligned with proper background frame + Grid: Subtle horizontal lines supporting readability + Legibility verdict: PASS - All text clearly readable against light background + + Dark render (plot-dark.png): + Background: Warm near-black #1A1A17 (correct) + Chrome: Title and labels now in light INK color (#F0EFE8) with excellent contrast + Data: Green, Orange, Blue colors identical to light render (only chrome adapted) + Data labels fully readable with proper coloring + Legend: Frame and text properly theme-adapted + Grid: Subtle lines adapted to dark theme + Legibility verdict: PASS - All text fully readable, no dark-on-dark failures + Theme adaptation: Data colors consistent between renders, chrome properly flips per theme criteria_checklist: visual_quality: - score: 36 - max: 40 + score: 28 + max: 30 items: - id: VQ-01 name: Text Legibility - score: 10 - max: 10 + score: 8 + max: 8 passed: true - comment: Title is large and bold (72px), axis labels at 48px, tick labels - at 36px - all perfectly readable + comment: All text readable in both light and dark themes with proper contrast - id: VQ-02 name: No Overlap - score: 8 - max: 8 + score: 6 + max: 6 passed: true - comment: No overlapping text, bars well-spaced, data labels clear + comment: Bars well-spaced with no colliding elements - id: VQ-03 name: Element Visibility - score: 8 - max: 8 + score: 6 + max: 6 passed: true - comment: Bars are appropriately sized with good groupPadding and pointPadding + comment: All markers and labels clearly visible - id: VQ-04 name: Color Accessibility - score: 5 - max: 5 + score: 2 + max: 2 passed: true - comment: Blue/Yellow/Purple palette is colorblind-safe, avoids red-green + comment: Okabe-Ito palette is CVD-safe - id: VQ-05 - name: Layout Balance - score: 3 - max: 5 + name: Layout & Canvas + score: 4 + max: 4 passed: true - comment: Good use of canvas but y-axis has excessive tick marks (every $10K - creates visual clutter) + comment: Excellent proportions at 4800x2700, nothing cut off - id: VQ-06 - name: Axis Labels + name: Axis Labels & Title score: 2 max: 2 passed: true - comment: 'Both axes have descriptive labels with units: "Quarter" and "Revenue - (thousands USD)"' + comment: Descriptive labels with units - id: VQ-07 - name: Grid & Legend + name: Palette Compliance score: 0 max: 2 + passed: false + comment: Data colors correct but limited distinctive styling beyond defaults + design_excellence: + score: 15 + max: 20 + items: + - id: DE-01 + name: Aesthetic Sophistication + score: 5 + max: 8 + passed: false + comment: Clean and professional but straightforward without custom elements + - id: DE-02 + name: Visual Refinement + score: 6 + max: 6 passed: true - comment: Grid lines are dashed but overly dense due to $10K intervals; legend - is well-placed but grid dominates + comment: Good refinement with subtle borders, proper spacing, elegant legend + - id: DE-03 + name: Data Storytelling + score: 4 + max: 6 + passed: false + comment: Clear story but lacks emphasis or focal point techniques 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 (column) chart - - id: SC-02 - name: Data Mapping score: 5 max: 5 passed: true - comment: Categories (quarters) on X, values on Y, groups (products) as series - - id: SC-03 + comment: Correct grouped bar chart + - id: SC-02 name: Required Features - score: 5 - max: 5 + score: 4 + max: 4 passed: true - comment: Distinct colors, clear legend, consistent bar widths, adequate spacing, - value labels present - - id: SC-04 - name: Data Range + comment: All features present + - id: SC-03 + name: Data Mapping score: 3 max: 3 passed: true - comment: Y-axis shows full range from 0 to above max value - - id: SC-05 - name: Legend Accuracy - score: 2 - max: 2 - passed: true - comment: Legend labels match series names correctly - - id: SC-06 - name: Title Format - score: 2 - max: 2 + comment: Categories and groups correctly mapped + - id: SC-04 + name: Title & Legend + score: 3 + max: 3 passed: true - comment: 'Uses correct format: "bar-grouped · highcharts · pyplots.ai"' + comment: Correct format and labels data_quality: - score: 18 - max: 20 + score: 15 + max: 15 items: - id: DQ-01 name: Feature Coverage score: 6 - max: 8 + max: 6 passed: true - comment: Shows quarterly comparison with 3 groups, demonstrates growth trends, - but could show more variation (all products trend upward) + comment: All chart aspects shown - 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, comprehensible business - scenario + comment: Realistic business scenario - id: DQ-03 name: Appropriate Scale - score: 5 - max: 5 + score: 4 + max: 4 passed: true - comment: Values in $156K-$398K range are realistic for quarterly revenue + comment: Sensible revenue values code_quality: - score: 7 + score: 10 max: 10 items: - id: CQ-01 @@ -169,42 +176,55 @@ review: score: 3 max: 3 passed: true - comment: 'Linear flow: imports → data → chart config → export' + comment: No unnecessary functions - id: CQ-02 name: Reproducibility - score: 0 - max: 3 - passed: false - comment: 'No random seed, but data is deterministic (hardcoded arrays) - PARTIAL: - data is fixed but no explicit seed documentation' + score: 2 + max: 2 + passed: true + comment: Deterministic data - id: CQ-03 name: Clean Imports score: 2 max: 2 passed: true - comment: All imports are used + 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: Uses current highcharts-core API + comment: Proper theme adaptation implementation - 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: 5 - max: 5 + comment: Correct filenames and theme-specific outputs + library_mastery: + score: 4 + max: 10 items: - - id: LF-01 - name: Uses distinctive library features - score: 5 + - id: LM-01 + name: Idiomatic Usage + score: 4 max: 5 passed: true - comment: 'Uses Highcharts-specific features: column chart type, dataLabels - with formatting, gridLineDashStyle, floating legend with shadow, subtitle, - formatted y-axis labels with ${value}K' + comment: Proper Chart/ColumnSeries usage with correct container specification + - id: LM-02 + name: Distinctive Features + score: 0 + max: 5 + passed: false + comment: No interactive features or advanced highcharts capabilities verdict: APPROVED +impl_tags: + dependencies: + - selenium + techniques: + - html-export + patterns: + - data-generation + dataprep: [] + styling: + - theme-adaptive