Skip to content

feat(letsplot): implement step-basic#5627

Merged
MarkusNeusinger merged 5 commits intomainfrom
implementation/step-basic/letsplot
Apr 30, 2026
Merged

feat(letsplot): implement step-basic#5627
MarkusNeusinger merged 5 commits intomainfrom
implementation/step-basic/letsplot

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

Implementation: step-basic - python/letsplot

Implements the python/letsplot version of step-basic.

File: plots/step-basic/implementations/python/letsplot.py

Parent Issue: #956


🤖 impl-generate workflow

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Apr 30, 2026

AI Review - Attempt 1/3

Image Description

Light render (plot-light.png): The plot renders on a warm off-white #FAF8F1 surface. A teal step line (#009E73) climbs from Month 1 (≈$45K) to Month 12 (≈$820K) in a clear staircase pattern, with circular markers at each monthly data point. Title "step-basic · letsplot · anyplot.ai" is positioned top-left in dark ink. Axis labels ("Month", "Cumulative Sales ($K)") and tick labels are dark and readable. Both horizontal and vertical grid lines are visible in a medium gray — somewhat prominent (INK_SOFT solid color rather than low-opacity RGBA). All text is readable against the light background — PASS.

Dark render (plot-dark.png): Same layout on a warm near-black #1A1A17 surface. The step line and markers remain the same #009E73 teal — identical to the light render as required. Title and axis labels switch to light text, tick labels use a softer light gray (#B8B7B0), all readable against the dark background. The grid lines are now light-colored and also remain somewhat prominent. No dark-on-dark failures observed. PASS.

Both renders are theme-correct with proper background colors and chrome flipping. Data color is identical across both themes.

Score: 85/100

Category Score Max
Visual Quality 29 30
Design Excellence 8 20
Spec Compliance 15 15
Data Quality 15 15
Code Quality 10 10
Library Mastery 8 10
Total 85 100

Visual Quality (29/30)

  • VQ-01: Text Legibility (8/8) — Title 24pt, axis labels 20pt, ticks 16pt, all explicitly set and readable in both themes
  • VQ-02: No Overlap (6/6) — 12 month ticks are evenly spaced, no collisions
  • VQ-03: Element Visibility (6/6) — Step line (size=2) and markers (size=6, alpha=0.9) are clearly visible
  • VQ-04: Color Accessibility (2/2) — Single teal series, colorblind-safe, good contrast on both backgrounds
  • VQ-05: Layout & Canvas (3/4) — Good proportions overall; minor top-whitespace gap above title
  • VQ-06: Axis Labels & Title (2/2) — Y-axis has units ($K), X-axis is descriptive
  • VQ-07: Palette Compliance (2/2) — First series is #009E73, backgrounds are #FAF8F1/#1A1A17, chrome flips correctly

Design Excellence (8/20)

  • DE-01: Aesthetic Sophistication (4/8) — Well-configured library default; brand green on clean minimal theme, but no distinctive design choices (no area fill, no focal point, no typographic hierarchy beyond size)
  • DE-02: Visual Refinement (2/6) — Minor grid is removed (good), but major grid uses solid INK_SOFT color instead of low-opacity RGBA (style guide: rgba(26,26,23,0.10)), and grid covers both axes rather than y-only (style guide: y-only for line/step charts)
  • DE-03: Data Storytelling (2/6) — Data shows cumulative growth but no visual hierarchy or emphasis — no annotation of key months, no area fill under the steps, no focal point guiding the viewer to an insight

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) — geom_step(direction="hv") is a correct step plot ("post" style)
  • SC-02: Required Features (4/4) — Step pattern, markers at data points, grid for tracing, appropriate step direction
  • SC-03: Data Mapping (3/3) — Month on X, cumulative sales on Y, all 12 data points visible
  • SC-04: Title & Legend (3/3) — Title matches {spec-id} · {library} · anyplot.ai; no legend needed (single series)

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) — Shows discrete jumps at each month, varying step heights, cumulative accumulation, and point markers at change moments
  • DQ-02: Realistic Context (5/5) — Monthly cumulative B2B/retail sales — neutral, business-relevant scenario
  • DQ-03: Appropriate Scale (4/4) — Monthly sales of $45K–$95K, cumulative $820K by year-end — plausible SMB figures

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3) — Linear flow: imports → tokens → data → plot → save
  • CQ-02: Reproducibility (2/2) — np.random.seed(42) set (data is hardcoded, so seed is redundant but harmless)
  • CQ-03: Clean Imports (2/2) — All imports from lets_plot are used in the theme/plot definition
  • CQ-04: Code Elegance (2/2) — Clean, Pythonic, appropriate complexity
  • CQ-05: Output & API (1/1) — Saves plot-{THEME}.png and plot-{THEME}.html correctly

Library Mastery (8/10)

  • LM-01: Idiomatic Usage (5/5) — Proper grammar-of-graphics composition with ggplot() + geom_step() + geom_point() + labs() + scale_x_continuous() + ggsize() + theme()
  • LM-02: Distinctive Features (3/5) — HTML export (ggsave(*.html)) is letsplot-distinctive; the step/point combination is standard ggplot2 API without unique letsplot differentiation

Score Caps Applied

  • None — DE-01 = 4 > 2, so the "correct but boring" cap (75) does not apply

Strengths

  • Perfect spec compliance with correct geom_step(direction="hv") and marker overlay
  • All three font size thresholds explicitly set (24/20/16pt), fully readable in both themes
  • Flawless theme-adaptive chrome: backgrounds, text, and grid all flip correctly between light and dark
  • Clean, linear code structure with idiomatic letsplot grammar-of-graphics

Weaknesses

  • Grid lines use solid INK_SOFT color instead of low-opacity RGBA (style guide: rgba(26,26,23,0.10) for light, rgba(240,239,232,0.10) for dark) — making the grid more prominent than intended
  • Both x-axis and y-axis major grid lines are shown — style guide recommends y-only for line/step charts
  • No visual storytelling: no area fill under the steps, no highlighted milestones, no focal point to guide the viewer
  • DE-01 aesthetic is functional but generic — the single-color step line on a minimal theme doesn't leverage design hierarchy

Issues Found

  1. DE-02 LOW: Grid is over-prominent and covers both axes
    • Fix: Change panel_grid_major to use RGBA low-opacity colors (e.g., "rgba(26,26,23,0.10)" light / "rgba(240,239,232,0.10)" dark); show y-axis grid only via panel_grid_major_x=element_blank()
  2. DE-03 LOW: No visual hierarchy or storytelling emphasis
    • Fix: Add a subtle filled area under the step line (geom_area with low alpha) or annotate a key milestone (e.g., "Midyear: $260K") to create a focal point; or use color emphasis on months with the largest jumps

AI Feedback for Next Attempt

Improve Design Excellence: (1) Use RGBA grid colors at ~10% opacity and show y-axis grid only (remove x-axis grid). (2) Add a translucent area fill under the step line using geom_ribbon or geom_area to add depth and visual weight. (3) Optionally annotate the final value or a notable inflection point to give the viewer a clear focal point and narrative anchor. These three changes alone would push DE-01 to 6, DE-02 to 4, and DE-03 to 4, lifting the total score above 90.

Verdict: REJECTED

@github-actions github-actions Bot added quality:85 Quality score 85/100 ai-rejected Quality not OK, triggers update labels Apr 30, 2026
@github-actions github-actions Bot added ai-attempt-1 First repair attempt and removed ai-rejected Quality not OK, triggers update labels Apr 30, 2026
@github-actions
Copy link
Copy Markdown
Contributor Author

🔧 Repair Attempt 1/4

Applied fixes based on AI review feedback.

Status: Repair completed, re-triggering review...


🤖 impl-repair

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Apr 30, 2026

AI Review - Attempt 2/3

Image Description

Light render (plot-light.png): The plot is rendered on a warm off-white background (#FAF8F1). The title "step-basic · letsplot · anyplot.ai" appears in dark text at the top-left. A brand-green (#009E73) step line traces 12 monthly cumulative sales values from 45 to 822 ($K), with matching green filled circles at each data point and a very light mint-green area fill (alpha=0.15) under the step. The y-axis label reads "Cumulative Sales ($K)" and the x-axis reads "Month" with integer ticks 1–12. A text annotation "Year-end total: $822K" appears in the upper-right area. The y-axis grid lines are subtle. One notable artifact: geom_area without color=\"transparent\" renders a thin diagonal border line running from (1, ~47) to (12, ~822) across the upper portion of the plot, visually resembling an unintended linear trend reference line. All text is clearly readable against the light background. Legibility verdict: PASS.

Dark render (plot-dark.png): The same plot on a warm near-black (#1A1A17) background. Title, axis labels, tick labels, and the year-end annotation all render in light-colored text, clearly readable against the dark surface. The brand green (#009E73) step line and data points are identical to the light render — only chrome elements (background, text, grid) have flipped to dark-mode tokens. The mint-green area fill is more subtle on the dark background but visible. The diagonal geom_area border artifact is also present but less prominent on the dark surface. No dark-on-dark text failures observed. Legibility verdict: PASS.

Both paragraphs are required. A review that only describes one render is invalid.

Score: 88/100

Category Score Max
Visual Quality 30 30
Design Excellence 12 20
Spec Compliance 15 15
Data Quality 15 15
Code Quality 10 10
Library Mastery 6 10
Total 88 100

Visual Quality (30/30)

  • VQ-01: Text Legibility (8/8) — All font sizes explicitly set: title=24, axis_title=20, axis_text=16; all readable in both themes
  • VQ-02: No Overlap (6/6) — No text collisions; annotation positioned cleanly in upper-right
  • VQ-03: Element Visibility (6/6) — Step line size=2 (6 after 3× scale), points size=6 (18 after scale); all clearly visible
  • VQ-04: Color Accessibility (2/2) — Single brand-green series, good contrast, CVD-safe
  • VQ-05: Layout & Canvas (4/4) — Plot fills canvas well; balanced margins; nothing cut off
  • VQ-06: Axis Labels & Title (2/2) — Y-axis has units: "Cumulative Sales ($K)"; X-axis "Month" is unambiguous
  • VQ-07: Palette Compliance (2/2) — First/only series is #009E73; backgrounds are #FAF8F1 (light) / #1A1A17 (dark); chrome is theme-adaptive

Design Excellence (12/20)

  • DE-01: Aesthetic Sophistication (5/8) — Above defaults: theme-adaptive chrome, brand-green area fill, year-end annotation, intentional layer composition (area + step + points + text). The diagonal geom_area outline artifact reduces polish below "strong design" level.
  • DE-02: Visual Refinement (3/6) — Explicit x-grid removal (panel_grid_major_x=element_blank()) and subtle y-grid show intentional refinement. However, the unintended diagonal geom_area border line is unpolished and should be fixed with color=\"transparent\".
  • DE-03: Data Storytelling (4/6) — Year-end total annotation provides a clear narrative anchor; area fill visually emphasizes the growth trajectory; step pattern highlights the discrete monthly contributions. Story is present but could be stronger with additional callout emphasis on high-growth months.

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) — geom_step(direction=\"hv\") correctly implements post-style step chart
  • SC-02: Required Features (4/4) — Step pattern ✓, markers at data points (geom_point) ✓, grid lines ✓
  • SC-03: Data Mapping (3/3) — X=month (1–12), Y=cumulative_sales; all 12 points visible
  • SC-04: Title & Legend (3/3) — Title "step-basic · letsplot · anyplot.ai" is correct; no legend needed (single series)

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) — Shows step pattern clearly with discrete jumps, area fill, and markers; varying monthly increments (not uniform) demonstrate all step-plot features
  • DQ-02: Realistic Context (5/5) — Monthly cumulative sales in a business year is a neutral, real-world scenario
  • DQ-03: Appropriate Scale (4/4) — Monthly sales 45–95K, cumulative 822K; plausible for a small-to-medium business

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3) — Linear flow: imports → tokens → data → plot → save; no functions/classes
  • CQ-02: Reproducibility (2/2) — np.random.seed(42) set
  • CQ-03: Clean Imports (2/2) — All imported symbols are used
  • CQ-04: Code Elegance (2/2) — Clean, Pythonic, no fake UI
  • CQ-05: Output & API (1/1) — Saves plot-{THEME}.png and plot-{THEME}.html; current API

Library Mastery (6/10)

  • LM-01: Idiomatic Usage (4/5) — Correct use of ggplot grammar of graphics; geom layering (area + step + point + text) is idiomatic lets-plot composition; scale_x_continuous for custom ticks
  • LM-02: Distinctive Features (2/5) — HTML export (plot-{THEME}.html) is a lets-plot distinctive feature. However, the core visualization could be replicated in plotnine with minimal syntax changes; no use of lets-plot-specific interactivity, tooltip mapping, or other features unique to this library.

Score Caps Applied

  • None — DE-01=5 > 2 and DE-02=3 > 2, so the "generic + no visual refinement" cap (75) does not apply.

Strengths

  • All text sizes explicitly set to spec-compliant values (title=24, labels=20, ticks=16) — full VQ-01 score
  • Layer composition (geom_area + geom_step + geom_point + geom_text) creates visual depth and is idiomatic to lets-plot's grammar-of-graphics style
  • Year-end total annotation ($822K) provides meaningful narrative context
  • Perfect theme-adaptive chrome: backgrounds, ink, grid, and annotation text all flip correctly between light and dark
  • Clean, linear code structure with proper seed and output files

Weaknesses

  • geom_area(fill=BRAND, alpha=0.15) without color=\"transparent\" renders a diagonal border line (the area polygon's top edge) that visually mimics an unintended linear trend reference line — fix with geom_area(fill=BRAND, alpha=0.15, color=\"transparent\")
  • LM-02 low: no use of distinctively lets-plot features beyond HTML export (e.g., interactive tooltips via aes(tooltip=...), geom_livemap, or stat transforms)

Issues Found

  1. DE-02 / geom_area border artifact: The area polygon outline creates a thin diagonal line across the plot, reducing visual refinement.
    • Fix: Add color=\"transparent\" to geom_area() call to hide the polygon border
  2. LM-02 LOW: Implementation is ggplot-generic rather than lets-plot-distinctive.
    • Fix: Consider adding tooltips=layer_tooltips().line(\"Month @month\").line(\"Cumulative: $@{cumulative_sales}K\") to a geom to showcase lets-plot's built-in tooltip system

AI Feedback for Next Attempt

Fix the geom_area diagonal border by adding color=\"transparent\". Optionally add a lets-plot tooltip definition (layer_tooltips()) to showcase the library's interactive tooltip capability, which would lift LM-02. The data storytelling and overall structure are solid — minor polish will push this to 90+.

Verdict: APPROVED

@github-actions github-actions Bot added quality:88 Quality score: 88/100 ai-approved Quality OK, ready for merge labels Apr 30, 2026
@MarkusNeusinger MarkusNeusinger merged commit 3a8b3b7 into main Apr 30, 2026
3 checks passed
@MarkusNeusinger MarkusNeusinger deleted the implementation/step-basic/letsplot branch April 30, 2026 13:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-approved Quality OK, ready for merge ai-attempt-1 First repair attempt quality:85 Quality score 85/100 quality:88 Quality score: 88/100

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant