diff --git a/plots/bump-basic/implementations/highcharts.py b/plots/bump-basic/implementations/highcharts.py index 74ccf2519c..81e97e586d 100644 --- a/plots/bump-basic/implementations/highcharts.py +++ b/plots/bump-basic/implementations/highcharts.py @@ -1,7 +1,7 @@ """ pyplots.ai bump-basic: Basic Bump Chart -Library: highcharts unknown | Python 3.13.11 -Quality: 92/100 | Created: 2025-12-23 +Library: highcharts 1.10.3 | Python 3.14.3 +Quality: 91/100 | Updated: 2026-02-22 """ import tempfile @@ -11,7 +11,7 @@ from highcharts_core.chart import Chart from highcharts_core.options import HighchartsOptions -from highcharts_core.options.series.area import LineSeries +from highcharts_core.options.series.spline import SplineSeries from selenium import webdriver from selenium.webdriver.chrome.options import Options @@ -21,88 +21,150 @@ weeks = ["Week 1", "Week 2", "Week 3", "Week 4", "Week 5", "Week 6"] # Rankings for each team across weeks (1 = best, 6 = worst) -# Designed to show various patterns: overtakes, stability, rise, fall +# Shows various patterns: overtakes, stability, rise, fall, swaps rankings = { - "Eagles": [3, 2, 1, 1, 2, 1], # Rise to top, brief dip, reclaim - "Wolves": [1, 1, 2, 3, 3, 2], # Start strong, fade then recover - "Tigers": [4, 3, 3, 2, 1, 3], # Steady rise to peak, then drop - "Bears": [2, 4, 4, 4, 4, 4], # Early drop, stabilize mid-table - "Sharks": [5, 5, 5, 5, 5, 5], # Consistently 5th - "Lions": [6, 6, 6, 6, 6, 6], # Consistently last + "Eagles": [3, 2, 1, 1, 2, 1], + "Wolves": [1, 1, 2, 3, 3, 2], + "Tigers": [4, 3, 3, 2, 1, 3], + "Bears": [2, 4, 5, 4, 4, 4], + "Sharks": [5, 5, 4, 5, 6, 5], + "Lions": [6, 6, 6, 6, 5, 6], } -# Colorblind-safe palette for 6 teams -colors = ["#306998", "#FFD43B", "#9467BD", "#17BECF", "#E377C2", "#8C564B"] +# Colorblind-safe palette starting with Python Blue +# Teal replaces red for better perceptual distance from orange under colorblindness +colors = ["#306998", "#FFD43B", "#9467BD", "#FF7F0E", "#17BECF", "#8C564B"] + +# Visual hierarchy: thicker lines for teams with dramatic rank changes +line_widths = { + "Eagles": 9, # rises to #1 — protagonist + "Wolves": 6, + "Tigers": 9, # dramatic arc #4→#1→#3 + "Bears": 5, + "Sharks": 4, # minor fluctuation + "Lions": 4, # mostly stable at bottom +} + +marker_radii = {"Eagles": 16, "Wolves": 12, "Tigers": 16, "Bears": 10, "Sharks": 9, "Lions": 9} -# Create chart +# Chart chart = Chart(container="container") chart.options = HighchartsOptions() -# Chart configuration chart.options.chart = { - "type": "line", + "type": "spline", "width": 4800, "height": 2700, "backgroundColor": "#ffffff", - "marginLeft": 250, - "marginRight": 250, + "marginLeft": 200, + "marginRight": 260, "marginBottom": 250, "spacingTop": 100, + "marginTop": 300, } # Title chart.options.title = { - "text": "bump-basic · highcharts · pyplots.ai", + "text": "bump-basic \u00b7 highcharts \u00b7 pyplots.ai", "style": {"fontSize": "72px", "fontWeight": "bold"}, } # Subtitle -chart.options.subtitle = {"text": "League Standings Over Season", "style": {"fontSize": "48px"}} +chart.options.subtitle = {"text": "League Standings Over Season", "style": {"fontSize": "48px", "color": "#666666"}} -# X-axis (weeks) +# X-axis chart.options.x_axis = { "categories": weeks, - "title": {"text": "Match Week", "style": {"fontSize": "48px"}, "margin": 30}, - "labels": {"style": {"fontSize": "36px"}, "y": 50}, - "lineWidth": 2, - "tickWidth": 2, - "gridLineWidth": 1, - "gridLineColor": "#e0e0e0", + "labels": {"style": {"fontSize": "40px"}}, + "lineWidth": 0, + "tickWidth": 0, + "gridLineWidth": 0, } -# Y-axis (rankings - inverted so rank 1 is at top) +# Y-axis (inverted so rank 1 is at top) chart.options.y_axis = { - "title": {"text": "Rank Position", "style": {"fontSize": "48px"}, "margin": 30}, - "labels": {"style": {"fontSize": "36px"}, "x": -15}, - "reversed": True, # Rank 1 at top - "min": 1, - "max": 6, + "title": {"text": "Rank", "style": {"fontSize": "40px", "color": "#444444"}}, + "labels": {"style": {"fontSize": "40px"}, "format": "#{value}"}, + "reversed": True, + "lineWidth": 0, + "min": 0.5, + "max": 6.5, "tickInterval": 1, + "startOnTick": False, + "endOnTick": False, "gridLineWidth": 1, - "gridLineDashStyle": "Dash", + "gridLineDashStyle": "Dot", "gridLineColor": "#e0e0e0", + "plotBands": [ + { + "from": 0.5, + "to": 1.5, + "color": "rgba(255, 215, 0, 0.06)", + "label": { + "text": "\u2605", + "align": "left", + "x": -60, + "style": {"fontSize": "36px", "color": "rgba(200, 170, 0, 0.35)"}, + }, + } + ], } -# Legend -chart.options.legend = { - "enabled": True, - "layout": "vertical", - "align": "right", - "verticalAlign": "middle", - "itemStyle": {"fontSize": "36px"}, - "itemMarginBottom": 15, -} +# Legend disabled — endpoint data labels already identify each team +chart.options.legend = {"enabled": False} + +# Tooltip disabled for static output +chart.options.tooltip = {"enabled": False} + +# Credits off +chart.options.credits = {"enabled": False} -# Plot options for line styling - bump charts need clear markers -chart.options.plot_options = {"line": {"lineWidth": 6, "marker": {"enabled": True, "radius": 14, "symbol": "circle"}}} +# Default plot options for spline +chart.options.plot_options = {"spline": {"marker": {"enabled": True, "symbol": "circle"}}} -# Add series for each team +# Series with data labels at endpoints, key-moment annotations, and visual hierarchy series_list = [] for i, team in enumerate(teams): - series = LineSeries() + ranks = rankings[team] + data_points = [] + for j, rank in enumerate(ranks): + point = {"y": rank} + if j == len(ranks) - 1: + # Data label at end point showing team name + point["dataLabels"] = { + "enabled": True, + "format": "{series.name}", + "align": "left", + "verticalAlign": "middle", + "x": 20, + "style": {"fontSize": "32px", "fontWeight": "bold", "color": colors[i], "textOutline": "3px white"}, + } + elif team == "Eagles" and j == 2: + # Storytelling: Eagles take #1 at Week 3 + point["dataLabels"] = { + "enabled": True, + "format": "\u2191 Takes lead", + "align": "center", + "y": -30, + "style": {"fontSize": "26px", "fontWeight": "normal", "color": "#555555", "textOutline": "2px white"}, + } + elif team == "Tigers" and j == 4: + # Storytelling: Tigers peak at #1 at Week 5 + point["dataLabels"] = { + "enabled": True, + "format": "\u2191 Peak", + "align": "center", + "y": -30, + "style": {"fontSize": "26px", "fontWeight": "normal", "color": "#555555", "textOutline": "2px white"}, + } + data_points.append(point) + + series = SplineSeries() series.name = team - series.data = rankings[team] + series.data = data_points series.color = colors[i] + series.line_width = line_widths[team] + series.marker = {"radius": marker_radii[team], "symbol": "circle"} series_list.append(series) chart.options.series = series_list @@ -126,12 +188,11 @@ """ -# Write temp HTML and take screenshot with tempfile.NamedTemporaryFile(mode="w", suffix=".html", delete=False, encoding="utf-8") as f: f.write(html_content) temp_path = f.name -# Also save as plot.html for interactive version +# Save interactive version Path("plot.html").write_text(html_content, encoding="utf-8") chrome_options = Options() @@ -143,8 +204,8 @@ driver = webdriver.Chrome(options=chrome_options) driver.get(f"file://{temp_path}") -time.sleep(5) # Wait for chart to render +time.sleep(5) driver.save_screenshot("plot.png") driver.quit() -Path(temp_path).unlink() # Clean up temp file +Path(temp_path).unlink() diff --git a/plots/bump-basic/metadata/highcharts.yaml b/plots/bump-basic/metadata/highcharts.yaml index f2c0ebe242..4e65d900c9 100644 --- a/plots/bump-basic/metadata/highcharts.yaml +++ b/plots/bump-basic/metadata/highcharts.yaml @@ -1,203 +1,246 @@ library: highcharts specification_id: bump-basic created: '2025-12-23T09:19:17Z' -updated: '2025-12-23T09:24:04Z' -generated_by: claude-opus-4-5-20251101 +updated: '2026-02-22T21:28:04Z' +generated_by: claude-opus-4-6 workflow_run: 20456612794 issue: 0 -python_version: 3.13.11 -library_version: unknown +python_version: 3.14.3 +library_version: 1.10.3 preview_url: https://storage.googleapis.com/pyplots-images/plots/bump-basic/highcharts/plot.png preview_thumb: https://storage.googleapis.com/pyplots-images/plots/bump-basic/highcharts/plot_thumb.png preview_html: https://storage.googleapis.com/pyplots-images/plots/bump-basic/highcharts/plot.html -quality_score: 92 +quality_score: 91 impl_tags: dependencies: - selenium techniques: + - annotations - html-export patterns: - data-generation - iteration-over-groups dataprep: [] - styling: [] + styling: + - grid-styling review: strengths: - - Correct implementation of bump chart with inverted Y-axis (rank 1 at top) - - Excellent colorblind-safe palette with 6 distinct colors - - 'Data demonstrates all bump chart patterns: overtakes, stability, rise, and fall' - - Perfect title format and clear subtitle context - - Well-sized markers and line widths for visibility - - Clean legend placement on the right side + - Excellent visual hierarchy through intentional line-weight and marker-size differentiation, + making Eagles and Tigers clearly the protagonists + - 'Clean design: legend removed in favor of endpoint labels, eliminating redundancy + from attempt 2' + - 'Strong data storytelling with annotations at key moments and gold plotBand for + #1 rank' + - Perfect spec compliance and data quality with diverse ranking patterns (overtakes, + rises, falls, stability) + - 'Improved color accessibility: teal replaces red for better colorblind safety' weaknesses: - - X-axis title Match Week not visible in the rendered image despite being configured - - LineSeries imported from highcharts_core.options.series.area instead of highcharts_core.options.series.line - image_description: 'The plot displays a bump chart showing league standings for - 6 sports teams (Eagles, Wolves, Tigers, Bears, Sharks, Lions) over 6 match weeks. - The Y-axis is correctly inverted with Rank 1 at the top and Rank 6 at the bottom. - Each team is represented by a colored line with circular markers at each week: - Eagles (blue), Wolves (yellow), Tigers (purple), Bears (cyan), Sharks (pink), - Lions (brown). The title "bump-basic · highcharts · pyplots.ai" is displayed prominently - at the top with a subtitle "League Standings Over Season". The legend is positioned - vertically on the right side. Lines show various patterns - Eagles rise to 1st, - Wolves start strong then fade, Tigers peak mid-season, Bears drop early and stabilize, - while Sharks and Lions remain consistently at 5th and 6th place respectively.' + - Top spacing (marginTop 300 + spacingTop 100) and right margin (260) are slightly + generous, reducing canvas utilization + - Annotations at 26px are small relative to the chart scale and could be more prominent + image_description: 'The plot displays a bump chart titled "bump-basic · highcharts + · pyplots.ai" with subtitle "League Standings Over Season" on a clean white background. + The Y-axis is labeled "Rank" and inverted with #1 at the top and #6 at the bottom, + using formatted labels (#1 through #6). The X-axis shows Week 1 through Week 6 + with no tick marks or grid lines. Six teams are plotted with smooth spline curves + and circle markers of varying sizes: Eagles (dark blue #306998, thick 9px line, + 16px markers) starts at #3, rises to #1 by Week 3, dips to #2 at Week 5, and finishes + at #1; Wolves (yellow #FFD43B, 6px line) starts at #1 and declines to #2 by end; + Tigers (purple #9467BD, thick 9px line) starts at #4, peaks at #1 in Week 5, then + drops to #3; Bears (orange #FF7F0E, 5px line) starts at #2 and falls to #4; Sharks + (teal #17BECF, thin 4px line) fluctuates around #4-6; Lions (brown #8C564B, thin + 4px line) stays mostly at #6 with a brief rise to #5 at Week 5. A subtle gold + plotBand highlights the #1 rank zone with a star symbol on the left edge. Two + storytelling annotations appear: "↑ Takes lead" above Eagles at Week 3 and "↑ + Peak" above Tigers at Week 5. Endpoint data labels on the right identify each + team by name in matching colors. Legend is disabled. Dotted gray grid lines mark + each rank on the Y-axis. The overall layout is clean and professional with intentional + visual hierarchy through line thickness and marker size.' criteria_checklist: visual_quality: - score: 37 - max: 40 + score: 29 + max: 30 items: - id: VQ-01 name: Text Legibility - score: 10 - max: 10 + score: 8 + max: 8 passed: true - comment: Title (72px), axis labels (48px), tick labels (36px) all clearly - readable at full size + comment: 'All font sizes explicitly set: title 72px, subtitle 48px, axis labels + 40px, y-axis title 40px, endpoint data labels 32px, annotations 26px. All + text clearly readable.' - id: VQ-02 name: No Overlap - score: 8 - max: 8 + score: 6 + max: 6 passed: true - comment: No overlapping text anywhere + comment: Legend removed. Endpoint labels well-spaced at unique ranks. Annotations + don't collide. Clean separation throughout. - id: VQ-03 name: Element Visibility - score: 8 - max: 8 + score: 6 + max: 6 passed: true - comment: Lines (6px width) and markers (14px radius) perfectly sized for 6 - teams + comment: Line widths 4-9px and marker radii 9-16px create intentional visual + hierarchy. All 6 teams easily distinguishable. - id: VQ-04 name: Color Accessibility - score: 5 - max: 5 + score: 4 + max: 4 passed: true - comment: Colorblind-safe palette with good contrast between all colors + comment: Custom palette avoids red-green issues. Teal replaces previous red. + All six colors well-separated for colorblind viewers. - id: VQ-05 - name: Layout Balance + name: Layout & Canvas score: 3 - max: 5 - passed: true - comment: Good proportions, but x-axis label "Match Week" is missing from the - visible plot + max: 4 + passed: false + comment: Chart fills ~55% of canvas. Right margin slightly larger than needed + now that legend is removed. Minor asymmetry. - id: VQ-06 - name: Axis Labels - score: 1 - max: 2 - passed: true - comment: '"Rank Position" is descriptive but no units needed; x-axis title - not visible' - - id: VQ-07 - name: Grid & Legend + name: Axis Labels & Title score: 2 max: 2 passed: true - comment: Subtle dashed grid lines, legend well-placed on right + comment: 'Y-axis title ''Rank'' with formatted labels #1-#6. X-axis shows + descriptive week categories.' + design_excellence: + score: 15 + max: 20 + items: + - id: DE-01 + name: Aesthetic Sophistication + score: 6 + max: 8 + passed: true + comment: Custom colorblind-safe palette, intentional line-weight hierarchy, + gold plotBand with star, spline curves, endpoint labels with text outlines. + Professional polish above defaults. + - id: DE-02 + name: Visual Refinement + score: 4 + max: 6 + passed: true + comment: 'Dotted grid lines, x-axis chrome removed, legend disabled, credits/tooltip + off. Some room: top spacing generous, right margin slightly oversized.' + - id: DE-03 + name: Data Storytelling + score: 5 + max: 6 + passed: true + comment: Visual hierarchy through line thickness/marker size highlights Eagles + and Tigers as protagonists. Gold plotBand and annotations mark key moments. + Viewer immediately grasps the competitive storyline. 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 bump chart showing rankings over time - - id: SC-02 - name: Data Mapping score: 5 max: 5 passed: true - comment: Weeks on X-axis, ranks on Y-axis, correctly inverted - - id: SC-03 + comment: Correct bump chart with spline curves, inverted Y-axis, rankings + over time. + - id: SC-02 name: Required Features - score: 5 - max: 5 + score: 4 + max: 4 passed: true - comment: Inverted Y-axis, distinct colors, dot markers, connected lines - - id: SC-04 - name: Data Range + comment: 'All spec features present: inverted Y-axis, distinct colors, dot + markers, connected lines, 6 entities, 6 periods.' + - id: SC-03 + name: Data Mapping score: 3 max: 3 passed: true - comment: Y-axis shows 1-6, X-axis shows all 6 weeks - - id: SC-05 - name: Legend Accuracy - score: 2 - max: 2 - passed: true - comment: All 6 team names correctly labeled - - id: SC-06 - name: Title Format - score: 2 - max: 2 + comment: X = time periods (weeks), Y = rank positions. All data correctly + plotted. + - id: SC-04 + name: Title & Legend + score: 3 + max: 3 passed: true - comment: Uses correct format "bump-basic · highcharts · pyplots.ai" + comment: Title follows exact format. Endpoint data labels identify all teams + with matching colors. 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 overtakes, stability, rise, fall patterns as spec requires + comment: 'Shows all bump chart patterns: overtakes, dramatic arcs, gradual + decline, stability, position swaps.' - id: DQ-02 name: Realistic Context - score: 7 - max: 7 + score: 5 + max: 5 passed: true - comment: Sports league standings is a natural bump chart application + comment: Sports league standings — real, comprehensible, neutral scenario + with plausible team names. - id: DQ-03 name: Appropriate Scale - score: 5 - max: 5 + score: 4 + max: 4 passed: true - comment: 6 teams, 6 weeks, ranks 1-6 are sensible values + comment: Rankings 1-6 for 6 teams over 6 weeks. Unique rankings, no ties. code_quality: - score: 7 + score: 10 max: 10 items: - id: CQ-01 name: KISS Structure - score: 1 + score: 3 max: 3 - passed: false - comment: Has functions via series loop, but follows simple sequential structure + passed: true + comment: 'Linear flow: Imports → Data → Chart config → Series loop → HTML + → Selenium. No functions or classes.' - id: CQ-02 name: Reproducibility - score: 3 - max: 3 - passed: false - comment: Deterministic data (no random), fully reproducible + score: 2 + max: 2 + passed: true + comment: All data hardcoded. No random elements. Fully deterministic. - id: CQ-03 name: Clean Imports - score: 1 + score: 2 max: 2 passed: true - comment: LineSeries imported from area module (unusual but works) + comment: 'All imports used: tempfile, time, urllib.request, Path, Chart, HighchartsOptions, + SplineSeries, webdriver, Options.' - 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: Clean series loop with dictionary-based per-team configuration. Conditional + data labels. Well-organized sections. - 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: Saves as plot.png via Selenium. Also saves plot.html. Current API. + library_mastery: + score: 7 + 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 Highcharts options, reversed axis, line series, but no advanced - features like data labels or tooltips in static output + comment: Correct use of Chart(container), HighchartsOptions, SplineSeries. + Dict-based config follows Highcharts conventions. Proper options hierarchy. + - id: LM-02 + name: Distinctive Features + score: 3 + max: 5 + passed: false + comment: 'Uses Highcharts-specific features: SplineSeries, plotBands with + label, per-point dataLabels, gridLineDashStyle. Doesn''t leverage more advanced + capabilities like linkedTo or custom events.' verdict: APPROVED