Skip to content

feat(seaborn): implement stem-basic#5629

Merged
MarkusNeusinger merged 5 commits intomainfrom
implementation/stem-basic/seaborn
Apr 30, 2026
Merged

feat(seaborn): implement stem-basic#5629
MarkusNeusinger merged 5 commits intomainfrom
implementation/stem-basic/seaborn

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

Implementation: stem-basic - python/seaborn

Implements the python/seaborn version of stem-basic.

File: plots/stem-basic/implementations/python/seaborn.py

Parent Issue: #972


🤖 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 displays a 30-point damped sinusoidal stem plot on a warm off-white background (~#FAF8F1). All stems and circular markers are rendered in teal green (#009E73). Stems are thin vertical lines running from the y=0 baseline to each data value. Markers are large, well-sized circles (~s=300). The baseline at y=0 is visible as a thin horizontal rule. Title "stem-basic · seaborn · anyplot.ai" is clearly readable in dark text. Axis labels "Sample Index (n)" and "Amplitude" are clearly readable. Tick labels on both axes are dark and readable against the light background. Top and right spines are removed. A very subtle grid is faintly visible. No legibility failures — all text reads clearly on the light surface.

Dark render (plot-dark.png): The same plot on a warm near-black background (~#1A1A17). All data elements (stems and markers) are in the same teal green (#009E73) — identical to the light render. Chrome has flipped correctly: title, axis labels, and tick labels are all light-colored and clearly readable against the dark background. The baseline at y=0 is visible. Grid lines are equally subtle. No dark-on-dark failures observed. Brand green #009E73 remains clearly visible on the dark surface. Legibility verdict: PASS for both renders.

⚠️ Code–Image Mismatch: The rendered images appear to have been generated from a different (corrected) version of the code than what is currently in seaborn.py. The committed code uses color="#306998" (Python Blue) for stems and color="#FFD43B" (yellow) for markers — but the images show uniform #009E73 teal. The committed code also saves to "plot.png" and has title "pyplots.ai", yet the images show "anyplot.ai" and are named correctly. The code as committed does not have theme-adaptation logic, yet the dark render shows proper theme adaptation. The code must be corrected to match what was actually generated.

Score: 80/100

Category Score Max
Visual Quality 28 30
Design Excellence 11 20
Spec Compliance 13 15
Data Quality 15 15
Code Quality 8 10
Library Mastery 5 10
Total 80 100

Visual Quality (28/30)

  • VQ-01: Text Legibility (8/8) — Font sizes explicitly set: title=24pt, labels=20pt, ticks=16pt; all readable in both themes
  • VQ-02: No Overlap (6/6) — No overlapping elements; 30 points well-spaced across x-axis
  • VQ-03: Element Visibility (6/6) — s=300 markers appropriate for 30 data points; stems clearly visible
  • VQ-04: Color Accessibility (2/2) — Single teal series, CVD-safe, high contrast on both surfaces
  • VQ-05: Layout & Canvas (4/4) — 16×9 canvas well-utilized; no cutoff; good margins
  • VQ-06: Axis Labels & Title (2/2) — "Sample Index (n)" and "Amplitude" are descriptive
  • VQ-07: Palette Compliance (0/2) — FAIL: Code contains color="#306998" (Python Blue) — explicit 0 per criteria; code has no ANYPLOT_THEME handling; output filename is "plot.png" not "plot-{THEME}.png"

Design Excellence (11/20)

  • DE-01: Aesthetic Sophistication (4/8) — Clean, professional look; spines removed; well-configured but not exceptional
  • DE-02: Visual Refinement (3/6) — Top/right spines removed ✓; but grid uses linestyle="--" (dashed) which contradicts style guide's solid-thin-lines requirement; alpha=0.3 slightly above recommended 10-15%
  • DE-03: Data Storytelling (4/6) — Damped sinusoidal impulse response creates a natural decay narrative; alternating positive/negative peaks create visual rhythm; viewer naturally follows the exponential envelope

Spec Compliance (13/15)

  • SC-01: Plot Type (5/5) — Correct: vertical lines (stems) from y=0 baseline to markers — canonical stem plot
  • SC-02: Required Features (4/4) — All spec requirements met: thin stems, visible circular markers, y=0 baseline, consistent sizing
  • SC-03: Data Mapping (3/3) — x=Sample Index, y=Amplitude; all 30 points visible; axes encompass full data range
  • SC-04: Title & Legend (1/3) — Code title string is "stem-basic · seaborn · pyplots.ai" — wrong domain (pyplots.ai instead of anyplot.ai); no legend needed for single series (N/A deduction avoided)

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) — Damped sinusoidal shows positive AND negative amplitudes, crossing zeros, decaying envelope — full stem plot feature space
  • DQ-02: Realistic Context (5/5) — Discrete impulse response in signal processing is a canonical real-world scientific use case; neutral domain
  • DQ-03: Appropriate Scale (4/4) — Amplitude ±~1.85 with exponential decay is physically realistic for a normalized impulse response

Code Quality (8/10)

  • CQ-01: KISS Structure (3/3) — Linear Imports → Data → Plot → Save; no functions/classes
  • CQ-02: Reproducibility (2/2) — np.random.seed(42) set
  • CQ-03: Clean Imports (2/2) — All four imports (matplotlib, numpy, pandas, seaborn) are actively used
  • CQ-04: Code Elegance (1/2) — Clean structure, but hardcoded non-compliant colors (#306998, #FFD43B) and absent theme adaptation reduce elegance
  • CQ-05: Output & API (0/1) — Saves to "plot.png" — must be f"plot-{THEME}.png"; also no ANYPLOT_THEME logic present

Library Mastery (5/10)

  • LM-01: Idiomatic Usage (3/5) — Correctly uses sns.scatterplot for marker rendering; hybrid vlines+scatter is the practical approach since seaborn lacks a native stemplot; axes-level API used correctly
  • LM-02: Distinctive Features (2/5) — Using seaborn's scatter specifically for marker rendering (with edgecolor, zorder, high s) is a seaborn-flavored choice; but overall the implementation is primarily matplotlib

Score Caps Applied

  • None — DE-01=4 > 2 and DE-02=3 > 2 (cap threshold requires BOTH ≤2); no other caps triggered

Strengths

  • Excellent data choice: damped sinusoidal impulse response is the canonical use case for stem plots and creates natural visual storytelling
  • Font sizes explicitly set at all three levels (24/20/16) — renders correctly at 4800×2700
  • Clean KISS code structure; reproducible with fixed seed
  • Marker sizing (s=300) and stem linewidth well-calibrated for 30 data points
  • Both rendered images pass theme-readability checks (all text readable in both themes)

Weaknesses

  • CRITICAL: Code uses color="#306998" (Python Blue) for stems and color="#FFD43B" for markers — neither is Okabe-Ito; replace both with #009E73 (single-series, Okabe-Ito position 1)
  • CRITICAL: No theme adaptation code — must add ANYPLOT_THEME = os.getenv("ANYPLOT_THEME", "light") and sns.set_theme(rc={...}) with PAGE_BG, INK, INK_SOFT tokens as specified in seaborn.md
  • CRITICAL: Output file is "plot.png" — must be f"plot-{THEME}.png" (run twice by pipeline)
  • MAJOR: Title contains "pyplots.ai" — must be "anyplot.ai"
  • MINOR: Grid uses linestyle="--" (dashed) — style guide requires solid thin lines; change to ax.yaxis.grid(True, alpha=0.15, linewidth=0.8)

Issues Found

  1. VQ-07 FAIL / CQ-05 FAIL: Missing ANYPLOT_THEME infrastructure — no os.getenv("ANYPLOT_THEME"), no sns.set_theme() with adaptive chrome, output saved to "plot.png" instead of "plot-{THEME}.png"
    • Fix: Add the full theme-adaptive setup block from prompts/library/seaborn.md; save as plt.savefig(f"plot-{THEME}.png", dpi=300, bbox_inches="tight", facecolor=PAGE_BG)
  2. VQ-07 FAIL: Colors #306998 and #FFD43B are not Okabe-Ito — Python palette colors are explicitly listed as non-compliant
    • Fix: Set single color #009E73 for stems; use same #009E73 for scatter markers (remove yellow fill)
  3. SC-04 deduction: Title domain name is "pyplots.ai" instead of "anyplot.ai"
    • Fix: ax.set_title("stem-basic · seaborn · anyplot.ai", fontsize=24)
  4. DE-02 deduction: Dashed grid (linestyle="--") contradicts style guide
    • Fix: ax.yaxis.grid(True, alpha=0.15, linewidth=0.8) — solid, subtle, y-axis only

AI Feedback for Next Attempt

Replace all hardcoded colors with Okabe-Ito (#009E73 for both stems and markers). Add the full ANYPLOT_THEME block (read env var, call sns.set_theme() with adaptive PAGE_BG/INK/INK_SOFT tokens, save as f"plot-{THEME}.png" with facecolor=PAGE_BG). Fix title to "anyplot.ai". Switch grid from dashed to solid subtle y-axis-only grid. These four fixes address all critical failures and should push the score above 90.

Verdict: REJECTED

@github-actions github-actions Bot added quality:80 Quality score 80/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
Attempt 1/3 - 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
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). It shows 30 discrete stem plot samples of a damped sinusoidal impulse response. Brand green (#009E73) stems extend vertically from a y=0 baseline to each data point, with large circular markers (edged in the background color for definition) sitting atop each stem. Amplitude ranges from approximately -1.0 to +1.85. The title "stem-basic · seaborn · anyplot.ai" is rendered in dark text at top-center. Axis labels "Sample Index (n)" and "Amplitude" are clearly readable. Tick labels along both axes are legible at appropriate size. A subtle horizontal grid with very low opacity is present. Top and right spines are removed. All text is clearly readable against the light background — no legibility issues.

Dark render (plot-dark.png): The same plot on a near-black background (#1A1A17). The data colors (brand green stems and markers) are visually identical to the light render — only chrome elements flip. Title, axis labels, and tick labels are rendered in light/cream tones and are fully readable against the dark background. The subtle grid remains visible. The baseline is visible as a slightly lighter horizontal rule. No dark-on-dark issues detected — tick labels are clearly light-colored on the dark background. Brand green #009E73 reads cleanly on the near-black surface.

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) — Title 24pt, axis labels 20pt, ticks 16pt; both themes fully legible
  • VQ-02: No Overlap (6/6) — 30 stems evenly spaced, no element collisions
  • VQ-03: Element Visibility (6/6) — Large markers (s=300) and 2.5px stems clearly visible; background-edged markers pop off the stems
  • VQ-04: Color Accessibility (2/2) — Single CVD-safe brand green, no red-green reliance
  • VQ-05: Layout & Canvas (4/4) — 16:9 proportions appropriate; nothing cut off; tight_layout used
  • VQ-06: Axis Labels & Title (2/2) — "Sample Index (n)" with units, "Amplitude" descriptive; title format correct
  • VQ-07: Palette Compliance (2/2) — First (only) series is #009E73; backgrounds #FAF8F1 / #1A1A17; both renders theme-correct

Design Excellence (12/20)

  • DE-01: Aesthetic Sophistication (5/8) — Professional polish; background-edged markers are a nice design touch; single-color simplicity is appropriate but leaves room for more visual interest
  • DE-02: Visual Refinement (4/6) — Top/right spines removed; y-axis-only grid at low opacity; generous whitespace; tight layout
  • DE-03: Data Storytelling (3/6) — Damped sinusoidal has a natural decay narrative, but no annotations or emphasis guide the viewer; an envelope curve or peak annotation would strengthen the story

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) — Correct stem plot: vertical lines from baseline to data values with circular markers
  • SC-02: Required Features (4/4) — Thin stems, visible circular markers, baseline at y=0, consistent sizing throughout
  • SC-03: Data Mapping (3/3) — X=sample index, Y=amplitude; all 30 data points visible; axes fully cover the data range
  • SC-04: Title & Legend (3/3) — "stem-basic · seaborn · anyplot.ai" correct; no legend needed for single series

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) — Both positive and negative stems shown; decaying oscillation demonstrates the plot type comprehensively; 30 points is within spec range
  • DQ-02: Realistic Context (5/5) — Damped sinusoidal impulse response is a canonical signal processing example; neutral and plausible
  • DQ-03: Appropriate Scale (4/4) — Amplitude range ~-1.0 to ~1.85, sample indices 0–29; realistic engineering values

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3) — Flat script, no functions or classes
  • CQ-02: Reproducibility (2/2) — np.random.seed(42) set
  • CQ-03: Clean Imports (2/2) — All five imports (os, matplotlib, numpy, pandas, seaborn) are used
  • CQ-04: Code Elegance (2/2) — Clean hybrid: seaborn scatterplot for markers, matplotlib vlines for stems — correct approach given seaborn has no native stem function
  • CQ-05: Output & API (1/1) — Saves as plot-{THEME}.png with correct facecolor and bbox_inches

Library Mastery (6/10)

  • LM-01: Idiomatic Usage (4/5) — sns.set_theme() with full rc dict is the idiomatic seaborn theming pattern; axes-level scatterplot used correctly; hybrid with matplotlib vlines is the right approach
  • LM-02: Distinctive Features (2/5) — Seaborn's contribution is limited to scatterplot markers and sns.set_theme() for theming; no seaborn-distinctive features (FacetGrid, statistical transforms, relplot, pairplot, etc.) are used; nearly all visualization logic is matplotlib

Score Caps Applied

  • None — no caps triggered

Strengths

  • Perfect visual quality: correct font sizes, both themes fully legible, no overlaps, correct palette
  • Excellent spec compliance: all stem plot requirements met (stems, markers, baseline)
  • Textbook data choice: damped sinusoidal impulse response is the canonical signal processing example
  • Background-edged scatter markers (edgecolor=PAGE_BG) create clean visual separation from stems
  • Theme-adaptive chrome correctly wired through sns.set_theme() rc params

Weaknesses

  • DE-03 limited: no annotations or visual emphasis to guide viewer through the decay narrative (e.g., envelope curve, peak annotation)
  • LM-02 low: seaborn used only for scatterplot + theming; no seaborn-distinctive techniques (statistical estimation, FacetGrid, etc.)

Issues Found

  1. DE-03 MODERATE: No visual storytelling beyond the raw data — the decay from peak to near-zero is a compelling story but nothing guides the eye
    • Fix: Could add a faded exponential envelope curve, or annotate the peak amplitude, or adjust marker size proportional to amplitude magnitude
  2. LM-02 LOW: Seaborn usage is minimal — the plot is essentially a matplotlib stem plot with seaborn theme and scatter markers
    • Fix: Use a seaborn-distinctive technique, e.g., use marker size scaling via the seaborn scatterplot size parameter, or use sns.despine() explicitly

AI Feedback for Next Attempt

Good solid foundation — keep the theme tokens, font sizes, data choice, and palette. To improve: (1) Add a visual storytelling element such as a faded exponential envelope curve (plot the envelope as a dashed line) to show the decay pattern explicitly — this earns DE-03 points. (2) Make seaborn earn its place more distinctively, e.g., use the seaborn scatterplot size parameter to scale marker size by |amplitude| to encode magnitude, or add a seaborn-styled legend/annotation. These changes would push LM-02 from 2 to 4.

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 44a1857 into main Apr 30, 2026
@MarkusNeusinger MarkusNeusinger deleted the implementation/stem-basic/seaborn branch April 30, 2026 15:05
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:80 Quality score 80/100 quality:88 Quality score: 88/100

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant