Skip to content

feat(letsplot): implement slope-basic#9910

Merged
MarkusNeusinger merged 6 commits into
mainfrom
implementation/slope-basic/letsplot
Jul 26, 2026
Merged

feat(letsplot): implement slope-basic#9910
MarkusNeusinger merged 6 commits into
mainfrom
implementation/slope-basic/letsplot

Conversation

@github-actions

Copy link
Copy Markdown
Contributor

Implementation: slope-basic - python/letsplot

Implements the python/letsplot version of slope-basic.

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

Parent Issue: #981


🤖 impl-generate workflow

github-actions Bot added 2 commits July 25, 2026 23:41
Regen from quality 85. Addressed:
- Canvas drift: previous ggsize(1600, 900)/scale=3 rendered at 4800x2700,
  outside the ±16px gate. Reset to canonical ggsize(800, 450)/scale=4 -> 3200x1800.
- Title missing the mandated language token; now "slope-basic · python ·
  letsplot · anyplot.ai".
- Label crowding (VQ-02): re-spread Q1/Q4 values so both endpoints keep a
  >=20-unit gap between adjacent entities instead of the previous ~10-unit
  clusters.
- Endpoint labels were overlapping their point markers because hjust alone
  doesn't create data-space clearance from a pixel-sized marker; added
  nudge_x to push labels a real distance away from each point.
- Re-tuned theme/geom_text sizes to the canonical canvas per the library
  prompt's sizing table (geom_text kept in the ~3-5mm annotation range
  instead of reusing the theme's pt scale).

Kept unchanged: Okabe-Ito-style increase/decrease coloring via the Imprint
palette, top-3 mover emphasis (bold vs. dimmed segments), layer_tooltips()
interactivity, and the consumer-electronics data scenario.
@claude

claude Bot commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

AI Review - Attempt 1/3

Image Description

Light render (plot-light.png): Warm off-white background (#FAF8F1-consistent). Title "slope-basic · python · letsplot · anyplot.ai" in dark ink, clearly readable. Y-axis "Sales ($K)" with tick labels 50–300 in dark/soft-dark ink. X-axis has no explicit title but uses "Q1 Sales ($K)" / "Q4 Sales ($K)" tick labels as the two time-point axis labels — all legible. Subtle horizontal-only grid. 10 entities connect Q1→Q4 via segments: green (#009E73) = Increase, matte red (#AE3030) = Decrease. The top-3 movers by absolute change (Headphones, Smart TVs, Smartphones) render bold and fully opaque; the other 7 lines are dimmed to ~40% alpha, creating a clear focal hierarchy. Entity+value labels sit at both endpoints without overlapping. One issue: a full rectangular panel border (all four sides) is visible instead of the style guide's default L-shaped frame. All text is readable against the light background — no light-on-light issues.

Dark render (plot-dark.png): Same layout on a warm near-black (#1A1A17-consistent) background. Title, axis title, and tick labels are all in light ink and clearly readable — no dark-on-dark failures. Data colors are pixel-identical to the light render (green #009E73 / red #AE3030), confirming only chrome flipped between themes. The same full rectangular panel-border issue is present here as well.

Both renders pass the theme-readability check; the panel-border issue is the main recurring flaw across both.

Score: 88/100

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

Visual Quality (28/30)

  • VQ-01: Text Legibility (7/8)
  • VQ-02: No Overlap (6/6)
  • VQ-03: Element Visibility (6/6)
  • VQ-04: Color Accessibility (1/2) - Dimmed 40%-alpha lines lean on red/green as the primary signal, reducing CVD distinguishability
  • VQ-05: Layout & Canvas (4/4)
  • VQ-06: Axis Labels & Title (2/2)
  • VQ-07: Palette Compliance (2/2)

Design Excellence (13/20)

  • DE-01: Aesthetic Sophistication (5/8) - Thoughtful top-mover emphasis and semantic color choice, but the full panel border undercuts the minimalist polish
  • DE-02: Visual Refinement (3/6) - Full rectangular panel border (all four spines) instead of the L-shaped default
  • DE-03: Data Storytelling (5/6) - Bold vs. dimmed lines create a clear focal point on the top-3 movers

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5)
  • SC-02: Required Features (4/4)
  • SC-03: Data Mapping (3/3)
  • SC-04: Title & Legend (3/3)

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6)
  • DQ-02: Realistic Context (5/5)
  • DQ-03: Appropriate Scale (4/4)

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3)
  • CQ-02: Reproducibility (2/2)
  • CQ-03: Clean Imports (2/2)
  • CQ-04: Code Elegance (2/2)
  • CQ-05: Output & API (1/1)

Library Mastery (7/10)

  • LM-01: Idiomatic Usage (4/5)
  • LM-02: Distinctive Features (3/5) - Custom layer_tooltips() differentiated for top movers is a genuine lets-plot-specific touch

Score Caps Applied

  • None

Strengths

  • Excellent data storytelling: top-3 movers by absolute change render bold and fully opaque while the other 7 lines are dimmed to alpha=0.40, creating a clear visual hierarchy toward the biggest Q1→Q4 changes
  • Correct, idiomatic slope-chart construction via geom_segment + geom_point + geom_text layering, with entity+value labels at both endpoints
  • Distinctive lets-plot feature: separate layer_tooltips() configs for top movers (with a "★ Top mover" title) vs. normal lines
  • Semantic color mapping (green=Increase, matte red=Decrease) matches the Imprint palette's documented semantic-exception guidance
  • Fully theme-adaptive chrome: data colors identical across themes, correct #FAF8F1/#1A1A17 backgrounds, all text tokens correctly threaded
  • Clean, deterministic, single-scope script — all imports used, no dead code

Weaknesses

  • Full rectangular panel border (all four spines) is visible in both renders instead of the default L-shaped (bottom+left only) frame — a slope chart isn't the "enclosed grid" exception
  • The alpha-blended (0.40) background lines reduce red/green distinguishability for CVD viewers; slope direction is a redundant cue but is subtle at low alpha across 10 overlapping lines

Issues Found

  1. DE-02 MEDIUM: Full box panel border deviates from the style guide's L-shaped spine default
    • Fix: Remove the panel border in theme() (e.g. panel_border=element_blank(), or equivalent) so only bottom/left axis lines remain
  2. VQ-04 LOW: Dimmed (alpha=0.40) lines weaken the red/green CVD distinction
    • Fix: Raise the alpha floor for the dimmed group (e.g. to ~0.5-0.55) or add a linetype difference as a secondary encoding

AI Feedback for Next Attempt

Remove the panel border so the plot uses the default L-shaped (bottom+left only) frame instead of a full box around all four sides. Also consider raising the alpha floor on the dimmed background lines (or adding a linetype distinction) so the Increase/Decrease color coding stays clearly distinguishable for colorblind viewers even when dimmed. Keep everything else as-is — the top-mover emphasis, custom tooltips, label placement, and theme-adaptive chrome are all working well.

Verdict: REJECTED

@github-actions github-actions Bot added quality:88 Quality score: 88/100 ai-rejected Quality not OK, triggers update labels Jul 25, 2026
@github-actions github-actions Bot added ai-attempt-1 First repair attempt and removed ai-rejected Quality not OK, triggers update labels Jul 25, 2026
Attempt 1/4 - fixes based on AI review
@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

claude Bot commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

AI Review - Attempt 2/3

Image Description

Light render (plot-light.png): Warm off-white background (#FAF8F1-consistent). Title "slope-basic · python · letsplot · anyplot.ai" in dark ink, fully visible, not clipped. Y-axis "Sales ($K)" title and 50-300 tick labels in dark/soft-dark ink, all readable. X-axis uses "Q1 Sales ($K)" / "Q4 Sales ($K)" tick labels as the two time-point axis labels. Subtle horizontal-only grid. The full box panel border from attempt 1 is gone — clean spine-free frame. 10 entities connect Q1→Q4: green (#009E73) = Increase, matte red (#AE3030) = Decrease. Top-3 movers by absolute change (Headphones, Smart TVs, Smartphones) render bold/opaque; the other 7 lines are dimmed and now also use a dashed linetype for Decrease vs solid for Increase, adding a CVD-safe redundant cue. Entity+value labels sit at both endpoints, evenly spaced, zero overlap. All text readable against the light background.

Dark render (plot-dark.png): Same layout on warm near-black (#1A1A17-consistent) background. Title, axis title, and tick labels are all light ink and clearly readable — no dark-on-dark failures. Data colors are pixel-identical to the light render, confirming only chrome flipped. Same clean spine-free frame and solid/dashed linetype distinction hold up on dark. All text readable against the dark background.

Both renders pass the theme-readability check; both attempt-1 findings (panel border, weak CVD signal) are resolved.

Score: 94/100

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

Visual Quality (29/30)

  • VQ-01: Text Legibility (7/8)
  • VQ-02: No Overlap (6/6)
  • VQ-03: Element Visibility (6/6)
  • VQ-04: Color Accessibility (2/2) - Fixed: linetype (solid=Increase, dashed=Decrease) now backs the color coding
  • VQ-05: Layout & Canvas (4/4)
  • VQ-06: Axis Labels & Title (2/2)
  • VQ-07: Palette Compliance (2/2)

Design Excellence (16/20)

  • DE-01: Aesthetic Sophistication (6/8) - Semantic color, top-mover emphasis, custom tooltips
  • DE-02: Visual Refinement (5/6) - Fixed: panel border removed, clean spine-free frame
  • DE-03: Data Storytelling (5/6) - Bold vs. dimmed lines create a clear focal point on top-3 movers

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5)
  • SC-02: Required Features (4/4)
  • SC-03: Data Mapping (3/3)
  • SC-04: Title & Legend (3/3)

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6)
  • DQ-02: Realistic Context (5/5)
  • DQ-03: Appropriate Scale (4/4)

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3)
  • CQ-02: Reproducibility (2/2)
  • CQ-03: Clean Imports (2/2)
  • CQ-04: Code Elegance (2/2)
  • CQ-05: Output & API (1/1)

Library Mastery (9/10)

  • LM-01: Idiomatic Usage (5/5)
  • LM-02: Distinctive Features (4/5) - Differentiated layer_tooltips() per top-mover status is a genuine lets-plot-specific touch

Score Caps Applied

  • None

Strengths

  • Panel-border issue from attempt 1 fully resolved — clean, spine-free frame in both renders
  • CVD-accessibility fix applied: scale_linetype_manual (solid/dashed) now backs the color coding as a redundant cue
  • Excellent data storytelling: top-3 movers by absolute change render bold/opaque while others are dimmed, creating a clear visual hierarchy
  • Distinctive lets-plot feature: separate layer_tooltips() configs for top movers ("★ Top mover") vs. normal lines
  • Entity+value labels at both endpoints, evenly spaced, zero overlap across 10 entities
  • Fully theme-adaptive chrome, deterministic single-scope script, all imports used

Weaknesses

  • Title occupies only ~45% of plot width at fontsize=16 — slightly under the 50-70% comfortable-fill guideline (not a deduction; doesn't overflow or look squeezed, but a touch more fontsize would improve visual balance)
  • At small (400px) preview scale the 10 entity+value labels become quite small — an inherent tension of a 10-entity slope chart rather than a fixable flaw here

Issues Found

No blocking issues found. Both attempt-1 findings (panel border, CVD signal) are confirmed fixed.

AI Feedback for Next Attempt

Implementation is approved. Optional future polish only: consider nudging the title fontsize up slightly (e.g. 17-18pt) to bring it closer to the 50-70% width guideline — purely cosmetic, not required.

Verdict: APPROVED

@github-actions github-actions Bot added quality:94 Quality score 94/100 ai-approved Quality OK, ready for merge and removed quality:88 Quality score: 88/100 labels Jul 26, 2026
@MarkusNeusinger
MarkusNeusinger merged commit b60a5ba into main Jul 26, 2026
@MarkusNeusinger
MarkusNeusinger deleted the implementation/slope-basic/letsplot branch July 26, 2026 00:03
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:94 Quality score 94/100

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant