diff --git a/plots/scatter-basic/implementations/python/highcharts.py b/plots/scatter-basic/implementations/python/highcharts.py index 61630d4523..740ee53087 100644 --- a/plots/scatter-basic/implementations/python/highcharts.py +++ b/plots/scatter-basic/implementations/python/highcharts.py @@ -1,7 +1,7 @@ """ anyplot.ai scatter-basic: Basic Scatter Plot Library: highcharts unknown | Python 3.14.4 -Quality: 88/100 | Created: 2026-04-23 +Quality: 85/100 | Updated: 2026-04-23 """ import os @@ -24,14 +24,15 @@ ELEVATED_BG = "#FFFDF6" if THEME == "light" else "#242420" INK = "#1A1A17" if THEME == "light" else "#F0EFE8" INK_SOFT = "#4A4A44" if THEME == "light" else "#B8B7B0" +INK_MUTED = "#6B6A63" if THEME == "light" else "#A8A79F" GRID = "rgba(26,26,23,0.10)" if THEME == "light" else "rgba(240,239,232,0.10)" BRAND = "#009E73" -# Data — study hours vs exam scores with moderate positive correlation +# Data — study hours vs exam scores, moderate positive correlation with realistic spread np.random.seed(42) -n_points = 120 -study_hours = np.random.normal(6, 1.8, n_points) -exam_scores = study_hours * 7.5 + np.random.normal(0, 6, n_points) + 30 +n_points = 180 +study_hours = np.random.gamma(shape=4.0, scale=1.4, size=n_points) +exam_scores = 38 + 6.2 * study_hours + np.random.normal(0, 7.5, n_points) exam_scores = np.clip(exam_scores, 0, 100) # Chart @@ -43,32 +44,58 @@ "width": 4800, "height": 2700, "backgroundColor": PAGE_BG, - "style": {"fontFamily": "'Inter', 'Segoe UI', Helvetica, Arial, sans-serif", "color": INK}, - "spacing": [60, 60, 60, 60], + "style": {"fontFamily": "'Inter', 'Helvetica Neue', Helvetica, Arial, sans-serif", "color": INK}, + "spacingTop": 80, + "spacingRight": 120, + "spacingBottom": 80, + "spacingLeft": 80, } chart.options.title = { "text": "scatter-basic · highcharts · anyplot.ai", - "style": {"fontSize": "64px", "fontWeight": "500", "color": INK}, - "margin": 50, + "align": "left", + "x": 40, + "style": {"fontSize": "68px", "fontWeight": "600", "color": INK, "letterSpacing": "-0.5px"}, + "margin": 20, +} + +chart.options.subtitle = { + "text": "Study hours versus exam performance across 180 students", + "align": "left", + "x": 40, + "style": {"fontSize": "32px", "fontWeight": "400", "color": INK_MUTED}, } chart.options.x_axis = { - "title": {"text": "Study Hours per Day", "style": {"fontSize": "44px", "color": INK}, "margin": 30}, - "labels": {"style": {"fontSize": "32px", "color": INK_SOFT}}, + "title": { + "text": "Study Hours per Day", + "style": {"fontSize": "40px", "fontWeight": "500", "color": INK}, + "margin": 28, + }, + "labels": {"style": {"fontSize": "28px", "color": INK_SOFT}, "y": 36}, "lineColor": INK_SOFT, + "lineWidth": 2, "tickColor": INK_SOFT, + "tickLength": 0, "gridLineWidth": 1, "gridLineColor": GRID, + "min": 0, + "max": 14, + "tickInterval": 2, } chart.options.y_axis = { - "title": {"text": "Exam Score (%)", "style": {"fontSize": "44px", "color": INK}, "margin": 30}, - "labels": {"style": {"fontSize": "32px", "color": INK_SOFT}}, + "title": {"text": "Exam Score (%)", "style": {"fontSize": "40px", "fontWeight": "500", "color": INK}, "margin": 28}, + "labels": {"style": {"fontSize": "28px", "color": INK_SOFT}, "x": -16}, "lineColor": INK_SOFT, + "lineWidth": 0, "tickColor": INK_SOFT, + "tickLength": 0, "gridLineWidth": 1, "gridLineColor": GRID, + "min": 0, + "max": 100, + "tickInterval": 20, } chart.options.legend = {"enabled": False} @@ -77,15 +104,27 @@ chart.options.tooltip = { "backgroundColor": ELEVATED_BG, "borderColor": INK_SOFT, - "borderRadius": 8, + "borderRadius": 10, "borderWidth": 1, - "style": {"fontSize": "26px", "color": INK}, + "shadow": False, + "style": {"fontSize": "28px", "color": INK}, "headerFormat": "", - "pointFormat": "Hours: {point.x:.1f}
Score: {point.y:.1f}", + "pointFormat": "{point.x:.1f} h study · {point.y:.0f}% score", } chart.options.plot_options = { - "scatter": {"marker": {"radius": 20, "symbol": "circle", "lineWidth": 2, "lineColor": PAGE_BG, "fillOpacity": 0.7}} + "scatter": { + "marker": { + "radius": 18, + "symbol": "circle", + "lineWidth": 2, + "lineColor": PAGE_BG, + "fillOpacity": 0.7, + "states": {"hover": {"enabled": True, "radiusPlus": 4, "lineWidthPlus": 1}}, + }, + "states": {"hover": {"halo": {"size": 14, "opacity": 0.18}}}, + "stickyTracking": False, + } } scatter = ScatterSeries() @@ -112,11 +151,9 @@ """ -# Save HTML artifact for the site with open(f"plot-{THEME}.html", "w", encoding="utf-8") as f: f.write(html_content) -# Render PNG via headless Chrome with tempfile.NamedTemporaryFile(mode="w", suffix=".html", delete=False, encoding="utf-8") as f: f.write(html_content) temp_path = f.name diff --git a/plots/scatter-basic/metadata/python/highcharts.yaml b/plots/scatter-basic/metadata/python/highcharts.yaml index ab1b745e7d..8413074dff 100644 --- a/plots/scatter-basic/metadata/python/highcharts.yaml +++ b/plots/scatter-basic/metadata/python/highcharts.yaml @@ -2,9 +2,9 @@ library: highcharts language: python specification_id: scatter-basic created: '2025-12-10T20:55:10Z' -updated: '2026-04-23T19:31:49Z' +updated: '2026-04-23T22:09:09Z' generated_by: claude-opus -workflow_run: 24853810886 +workflow_run: 24860900308 issue: 611 python_version: 3.14.4 library_version: unknown @@ -12,43 +12,40 @@ preview_url_light: https://storage.googleapis.com/anyplot-images/plots/scatter-b preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/scatter-basic/python/highcharts/plot-dark.png preview_html_light: https://storage.googleapis.com/anyplot-images/plots/scatter-basic/python/highcharts/plot-light.html preview_html_dark: https://storage.googleapis.com/anyplot-images/plots/scatter-basic/python/highcharts/plot-dark.html -quality_score: 88 +quality_score: 85 review: strengths: - - Perfect theme adaptation across both renders — warm backgrounds, fully adaptive - chrome, data colors unchanged between light and dark - - All required spec features correctly implemented with good data choices (120 points, - fillOpacity=0.7, grid lines, descriptive labels) - - 'Exemplary code quality: clean flat structure, seeded RNG, all imports used, modern - Python conventions (zip strict=True)' - - Font sizes explicitly set and well-proportioned for 4800x2700 canvas (title 64px, - labels 44px, ticks 32px) - - 'White-adaptive marker outlines (lineColor: PAGE_BG) cleverly adapt to both light - and dark themes' + - 'Full theme-adaptive chrome: all INK, INK_SOFT, INK_MUTED, GRID, PAGE_BG, ELEVATED_BG + tokens wired correctly — both renders are fully readable' + - 'Complete spec compliance: correct title format, transparency, grid, 180 points' + - 'Excellent code quality: seed set, clean imports, KISS structure, container.screenshot() + for precise element capture' + - 'Proper Highcharts idioms: inline JS download prevents CDN/headless failure, container + parameter present' weaknesses: - - 'DE-01 (4/8): No visual hierarchy beyond single brand-green color; the aesthetic - is polished but generic — missing a focal point, size encoding, or any element - that draws the eye' - - 'DE-03 (2/6): The upward correlation is implied by data but not communicated — - no trend line, no R² annotation, no emphasis highlighting the key relationship' - - 'LM-02 (3/5): Only basic scatter features used; adding a regression trend line - as a second LineSeries would add visual hierarchy and showcase Highcharts multi-series - composition' + - 'Design excellence needs improvement: add a linear regression trendline or reference + band to create a visual focal point (DE-03); consider removing outer chart border/frame + for a more minimal look (DE-02)' + - 'Axis ranges leave notable empty space: x-axis extends 2+ hours beyond actual + data; y-axis starts at 0 but data begins ~30% — tighten ranges or add padding + so the data fills more of the plot area (VQ-05, DQ-03)' + - Point density in the 4-8 hour cluster makes individual markers hard to distinguish + — consider reducing radius slightly or a subtle alpha decrease (VQ-03) image_description: |- Light render (plot-light.png): - Background: Warm off-white matching #FAF8F1 — not pure white, correct theme surface - Chrome: Title "scatter-basic · highcharts · anyplot.ai" in dark text, clearly readable; x-axis label "Study Hours per Day" and y-axis label "Exam Score (%)" readable; tick labels small but legible in dark color - Data: ~120 circular markers in #009E73 brand green with white-adaptive outlines and 0.7 opacity; clear positive correlation pattern visible; subtle grid lines on both axes - Legibility verdict: PASS — all text readable against light background, no light-on-light failures + Background: Warm off-white #FAF8F1 — correct, not pure white + Chrome: Title "scatter-basic · highcharts · anyplot.ai" in dark ink (#1A1A17), clearly readable at ~68px. Subtitle in muted dark (#6B6A63). Axis labels "Study Hours per Day" and "Exam Score (%)" in dark ink with units. Tick labels in dark secondary ink (#4A4A44), all readable. + Data: 180 green (#009E73) circular markers with page-background-color edges, radius 18, fillOpacity 0.7. Clear positive correlation pattern visible. + Legibility verdict: PASS — all text readable against light background Dark render (plot-dark.png): - Background: Warm near-black matching #1A1A17 — not pure black, correct theme surface - Chrome: Title, axis labels, and tick labels all render in light colors (near-white / soft grey); clearly readable against dark surface; no dark-on-dark failures detected - Data: Identical #009E73 brand green markers — data colors unchanged from light render, confirming correct theme separation; grid lines subtle and visible - Legibility verdict: PASS — all text light-colored and readable against dark background, no legibility failures + Background: Warm near-black #1A1A17 — correct, not pure black + Chrome: Title switches to light #F0EFE8, subtitle to #A8A79F, axis labels and ticks to #B8B7B0 — all light-colored and readable. No dark-on-dark failures observed. + Data: Same #009E73 green markers — identical to light render (only chrome flips) + Legibility verdict: PASS — all text readable against dark background, no dark-on-dark failures criteria_checklist: visual_quality: - score: 30 + score: 28 max: 30 items: - id: VQ-01 @@ -56,71 +53,73 @@ review: score: 8 max: 8 passed: true - comment: 'All font sizes explicitly set: title 64px, axis labels 44px, tick - labels 32px, tooltip 26px; fully readable in both themes' + comment: 'All font sizes explicitly set: title 68px, axis labels 40px, ticks + 28px; readable in both themes' - id: VQ-02 name: No Overlap score: 6 max: 6 passed: true - comment: No text overlap; data density handled by fillOpacity=0.7 + comment: No text collisions; marker overlap handled by fillOpacity 0.7 with + white edges - id: VQ-03 name: Element Visibility - score: 6 + score: 5 max: 6 passed: true - comment: radius=20 with white outline and 0.7 opacity well-calibrated for - 120 points + comment: Radius 18 markers visible; dense cluster in 4-7 hour range makes + individual points harder to isolate - id: VQ-04 name: Color Accessibility score: 2 max: 2 passed: true - comment: Single Okabe-Ito series, good contrast, CVD-safe + comment: 'Single series #009E73 on both surfaces; high contrast, CVD-safe' - id: VQ-05 name: Layout & Canvas - score: 4 + score: 3 max: 4 passed: true - comment: 60px spacing all sides, plot area fills canvas well, balanced margins + comment: Good proportions; x-axis extends to 14 with almost no data past 12, + y-axis starts at 0 with no data below ~30% - id: VQ-06 name: Axis Labels & Title score: 2 max: 2 passed: true - comment: Study Hours per Day and Exam Score (%) with units + comment: Study Hours per Day and Exam Score (%) are descriptive with units - id: VQ-07 name: Palette Compliance score: 2 max: 2 passed: true - comment: 'First series #009E73; #FAF8F1/#1A1A17 backgrounds; theme-correct - chrome in both renders' + comment: 'First series #009E73; light bg #FAF8F1; dark bg #1A1A17; full theme-adaptive + chrome' design_excellence: - score: 10 + score: 12 max: 20 items: - id: DE-01 name: Aesthetic Sophistication - score: 4 + score: 5 max: 8 - passed: false - comment: Clean, polished default — custom font stack and brand color but no - visual hierarchy, focal point, or exceptional design element + passed: true + comment: 'Above default: left-aligned title, Inter font, white marker edges, + subtitle; not yet publication-ready' - id: DE-02 name: Visual Refinement score: 4 max: 6 - passed: false - comment: 'Above default: explicit 60px spacing, marker adaptive outlines, - 10%-opacity grid; clean layout without Highcharts frame' + passed: true + comment: Legend disabled, credits off, tick marks removed, subtle grid, generous + spacing - id: DE-03 name: Data Storytelling - score: 2 + score: 3 max: 6 passed: false - comment: Positive correlation visible but not communicated — no trend line, - no R² annotation, no focal emphasis + comment: Subtitle adds context; positive correlation apparent; no trendline + or emphasis to guide viewer spec_compliance: score: 15 max: 15 @@ -130,50 +129,53 @@ review: score: 5 max: 5 passed: true - comment: Correct scatter plot via ScatterSeries + comment: Correct scatter plot - id: SC-02 name: Required Features score: 4 max: 4 passed: true - comment: fillOpacity=0.7, axis labels, grid lines, 120 points within spec - range + comment: Transparency fillOpacity 0.7, axis labels, title, grid lines all + present - id: SC-03 name: Data Mapping score: 3 max: 3 passed: true - comment: Study hours on X, exam scores on Y; all data visible + comment: Study hours on x (independent), exam score on y (dependent); 180 + points - id: SC-04 name: Title & Legend score: 3 max: 3 passed: true - comment: Exact title format; legend correctly disabled for single series + comment: Title scatter-basic · highcharts · anyplot.ai; single-series legend + disabled data_quality: - score: 15 + score: 13 max: 15 items: - id: DQ-01 name: Feature Coverage - score: 6 + score: 5 max: 6 passed: true - comment: Clear positive correlation with natural spread and upper-bound clipping; - 120 points cover full scatter range + comment: Shows correlation, distribution, and overlap pattern; single-group + limits variety - id: DQ-02 name: Realistic Context score: 5 max: 5 passed: true - comment: Study hours vs exam scores — classic, neutral, education domain + comment: 'Study hours vs. exam scores: neutral, educational, real-world plausible' - id: DQ-03 name: Appropriate Scale - score: 4 + score: 3 max: 4 passed: true - comment: 'Hours: 1.2–9.5 (mean 6, std 1.8); Scores: 36–100%; clip at 100 is - realistic' + comment: Values are domain-realistic; gamma distribution produces few points + past 10 hours while axis extends to 14; no data below ~30% while y starts + at 0 code_quality: score: 10 max: 10 @@ -183,56 +185,56 @@ review: score: 3 max: 3 passed: true - comment: 'Flat: imports → tokens → data → chart config → series → HTML → PNG' + comment: 'Sequential: tokens -> data -> chart -> HTML -> Selenium; no functions/classes' - id: CQ-02 name: Reproducibility score: 2 max: 2 passed: true - comment: np.random.seed(42) set + comment: np.random.seed(42) - id: CQ-03 name: Clean Imports score: 2 max: 2 passed: true - comment: All 11 imports used; no unused entries + comment: All imports used - id: CQ-04 name: Code Elegance score: 2 max: 2 passed: true - comment: Clean, Pythonic; zip(strict=True) is a modern Python touch; no over-engineering + comment: Clean, idiomatic; container.screenshot() preferred over driver.save_screenshot - id: CQ-05 name: Output & API score: 1 max: 1 passed: true - comment: Saves plot-{THEME}.png and plot-{THEME}.html; element-level screenshot + comment: Saves plot-{THEME}.png and plot-{THEME}.html library_mastery: - score: 8 + score: 7 max: 10 items: - id: LM-01 name: Idiomatic Usage - score: 5 + score: 4 max: 5 passed: true - comment: Expert use of Chart(container='container'), HighchartsOptions, ScatterSeries; - follows recommended highcharts-core pattern + comment: Chart(container=container), ScatterSeries, HighchartsOptions, to_js_literal(), + inline JS download — all correct patterns - id: LM-02 name: Distinctive Features score: 3 max: 5 - passed: false - comment: Uses inline JS embedding, to_js_literal(), and pointFormat template - syntax; no Highcharts-unique visualization feature (regression, boost, drilldown) + passed: true + comment: Custom tooltip pointFormat, HTML export, hover state configuration, + fillOpacity via plotOptions.scatter verdict: REJECTED impl_tags: dependencies: - selenium techniques: - - html-export - hover-tooltips + - html-export patterns: - data-generation dataprep: []