Skip to content

feat(seaborn): implement indicator-ema#7342

Merged
MarkusNeusinger merged 4 commits into
mainfrom
implementation/indicator-ema/seaborn
May 19, 2026
Merged

feat(seaborn): implement indicator-ema#7342
MarkusNeusinger merged 4 commits into
mainfrom
implementation/indicator-ema/seaborn

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

Implementation: indicator-ema - python/seaborn

Implements the python/seaborn version of indicator-ema.

File: plots/indicator-ema/implementations/python/seaborn.py

Parent Issue: #3652


🤖 impl-generate workflow

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented May 19, 2026

AI Review - Attempt 1/3

Image Description

Light render (plot-light.png): The chart displays three overlapping time-series lines on a warm off-white (#FAF8F1) background across ~150 trading days (2024-03 to 2024-10). The Close Price line is rendered in brand green (#009E73) at slightly greater thickness, EMA 12 in vermillion/orange (#D55E00), and EMA 26 in blue (#0072B2) — all matching Okabe-Ito positions 1–3. A single bullish crossover marker (green upward triangle) appears in the early period and one bearish marker (orange downward triangle) near mid-July. The x-axis is labeled "Date" with rotated date ticks; the y-axis is labeled "Price (USD)" with price range ~155–225. Top and right spines are removed; a very subtle y-axis grid is present. The legend (upper-left) lists all three series. The title reads "indicator-ema · python · seaborn · anyplot.ai". All title, axis labels, tick labels, and legend text are clearly readable against the light background. Legibility verdict: PASS.

Dark render (plot-dark.png): Identical layout on a near-black (#1A1A17) background. The data colors are identical to the light render — green Close Price, orange EMA 12, blue EMA 26 — confirming only chrome (background, text, grid) has adapted. Title, axis labels, tick labels, and legend text all appear in light/warm-white tones against the dark surface; no dark-on-dark failures are present. Crossover markers remain visible. The legend box uses the elevated dark fill (#242420). Legibility verdict: PASS.

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 bold, axis labels 20pt, ticks 16pt, legend 16pt; all readable in both themes
  • VQ-02: No Overlap (6/6) — Legend positioned clear of data, no collisions
  • VQ-03: Element Visibility (6/6) — All three lines clearly distinguishable; crossover markers prominent at s=250
  • VQ-04: Color Accessibility (2/2) — Okabe-Ito positions 1–3 are CVD-safe; no red-green sole signal
  • VQ-05: Layout & Canvas (4/4) — 16:9 landscape appropriate for time-series; nothing cut off
  • VQ-06: Axis Labels & Title (2/2) — "Date" and "Price (USD)" with units; title format correct
  • VQ-07: Palette Compliance (2/2) — First series #009E73, correct Okabe-Ito order, backgrounds #FAF8F1/#1A1A17

Design Excellence (12/20)

  • DE-01: Aesthetic Sophistication (5/8) — Custom Okabe-Ito palette, deliberate line-weight hierarchy (3.5/2.5), crossover markers demonstrate design thought; overall composition is clean but standard
  • DE-02: Visual Refinement (4/6) — Top/right spines removed, y-only grid at alpha=0.10, adequate whitespace via tight_layout
  • DE-03: Data Storytelling (3/6) — Price line thicker for focal hierarchy; crossover markers guide viewer to key signal moments; no textual annotations to explain signals

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) — EMA overlay chart with price + two EMA lines; correct type
  • SC-02: Required Features (4/4) — Price line prominent, two EMAs overlaid with distinct colors, EMAs thinner, crossover points highlighted with bullish/bearish distinction
  • SC-03: Data Mapping (3/3) — Date on x, Price (USD) on y; 150 business-day periods (within 60–200 spec range)
  • SC-04: Title & Legend (3/3) — Title matches "indicator-ema · python · seaborn · anyplot.ai" exactly; legend labels "Close Price", "EMA 12", "EMA 26"

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) — Price line, 12-day EMA, 26-day EMA, crossover detection (bullish/bearish markers) all present
  • DQ-02: Realistic Context (5/5) — Stock starting at ~00, 150 business days (Mar–Oct 2024), standard MACD periods (12/26); neutral and plausible
  • DQ-03: Appropriate Scale (4/4) — Price range ~55–25 realistic for a mid-cap stock; 150 points within spec range

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)
  • CQ-03: Clean Imports (2/2) — os, matplotlib, numpy, pandas, seaborn all used
  • CQ-04: Code Elegance (2/2) — Pandas ewm for EMA, shift-based crossover detection, melt for idiomatic seaborn hue grouping; clean and well-organized
  • CQ-05: Output & API (1/1) — Saves as plot-{THEME}.png with correct dpi and facecolor

Library Mastery (6/10)

  • LM-01: Idiomatic Usage (4/5) — sns.lineplot with hue on melted long-format DataFrame is idiomatic; sns.set_theme for theming; axes-level API with ax parameter; crossover markers use raw plt.scatter (acceptable but not seaborn-native)
  • LM-02: Distinctive Features (2/5) — Wide-to-long melt enabling hue-based multi-series grouping is a genuinely distinctive seaborn pattern; limited beyond this

Score Caps Applied

  • None

Strengths

  • Perfect Okabe-Ito palette compliance with correct order (#009E73 as first series)
  • Crossover detection (bullish/bearish markers) fully implements the spec's optional feature, adding real data storytelling value
  • Idiomatic seaborn usage: wide-to-long melt + sns.lineplot hue grouping produces a clean auto-legend
  • Full theme adaptation across all chrome elements (backgrounds, text, grid, legend, markers) with correct tokens

Weaknesses

  • Design Excellence is functional but not distinguished — no annotations explaining what crossover signals mean to a viewer unfamiliar with EMA trading theory
  • Library Mastery LM-02 is modest — the implementation relies on matplotlib scatter for crossover markers instead of exploring seaborn-native approaches

Issues Found

  1. DE-03 MODERATE: Crossover markers identify signal points but no visual context (e.g., a brief annotation or shaded region) communicates their significance — viewer must infer the bullish/bearish meaning
    • Fix: Add small text annotations ("Golden Cross", "Death Cross") near the markers, or shade the region between EMA lines green/red to indicate trend direction
  2. LM-02 LOW: Crossover markers implemented with raw — seaborn's with a filtered DataFrame would be more consistent
    • Fix: Replace with

AI Feedback for Next Attempt

The core implementation is strong — palette, theming, data, and spec compliance are all correct. To improve Design Excellence: (1) add brief annotations at crossover markers to guide interpretation (e.g., small "↑ Golden Cross" / "↓ Death Cross" labels or a shaded band between EMA lines reflecting trend direction); (2) replace raw matplotlib scatter with sns.scatterplot for crossover markers to improve library consistency. Keep the existing line-weight hierarchy and Okabe-Ito palette unchanged.

Verdict: APPROVED

@github-actions github-actions Bot added quality:88 Quality score: 88/100 ai-rejected Quality not OK, triggers update labels May 19, 2026
@github-actions github-actions Bot added ai-attempt-1 First repair attempt and removed ai-rejected Quality not OK, triggers update labels May 19, 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 May 19, 2026

AI Review - Attempt 2/3

Image Description

Light render (plot-light.png): The plot renders on a warm off-white #FAF8F1 background with a clean L-shaped frame (top and right spines removed). Three lines are shown: Close Price in Okabe-Ito green (#009E73, thickest at 3.5px), EMA 12 in vermillion (#D55E00, 2.5px), and EMA 26 in blue (#0072B2, 2.5px). The price traces a clear decline from ~$225 in early March 2024 to a low near $155 in May, then recovers partially through October. A bearish crossover marker (down-triangle, vermillion) is clearly visible around August 2024. The legend sits in the upper-left with a styled elevated background. X-axis shows date labels (2024-03 through 2024-10) rotated 30°. Y-axis is labelled "Price (USD)". Title reads "indicator-ema · python · seaborn · anyplot.ai" in bold at 24pt. All text is fully readable against the light background. Legibility verdict: PASS.

Dark render (plot-dark.png): The same chart renders on a warm near-black #1A1A17 background. All three data line colors are identical to the light render — green Close Price, vermillion EMA 12, blue EMA 26 — confirming only chrome flips. Title, axis labels, tick labels, and legend text are all rendered in light ink tokens (#F0EFE8 / #B8B7B0), with no dark-on-dark failures. The bearish crossover triangle is still clearly visible. Grid lines are very subtle (alpha 0.10) against the dark background. Legibility verdict: PASS.

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

Score: 90/100

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

Visual Quality (28/30)

  • VQ-01: Text Legibility (8/8) — Title 24pt, axis labels 20pt, ticks 16pt, legend 16pt all explicitly set; readable in both themes
  • VQ-02: No Overlap (6/6) — X-axis dates rotated 30°, legend positioned upper-left away from data, no collisions
  • VQ-03: Element Visibility (6/6) — Price line 3.5px, EMA lines 2.5px, crossover markers s=250 — all clearly distinguishable
  • VQ-04: Color Accessibility (2/2) — Okabe-Ito is CVD-safe; three series have good luminance contrast
  • VQ-05: Layout & Canvas (4/4) — 16:9 canvas well-utilized; balanced margins; data fills the plot area
  • VQ-06: Axis Labels & Title (2/2) — Y-axis "Price (USD)" with units; X-axis "Date"
  • VQ-07: Palette Compliance (2/2) — First series #009E73; EMA 12 #D55E00; EMA 26 #0072B2; correct Okabe-Ito order; backgrounds #FAF8F1 / #1A1A17; theme-adaptive chrome fully correct in both renders

Design Excellence (14/20)

  • DE-01: Aesthetic Sophistication (5/8) — Above well-configured default: intentional line-width hierarchy, crossover markers with directional symbolism, clean typography. Falls short of strong design (6) due to absence of fills (e.g. shaded region between EMA lines) or background trend bands that would add visual depth
  • DE-02: Visual Refinement (5/6) — Top/right spines removed; remaining spines coloured with INK_SOFT; y-axis-only grid at alpha=0.10; legend styled with ELEVATED_BG frame; tight_layout applied. Genuinely refined above defaults
  • DE-03: Data Storytelling (4/6) — Crossover marker creates a clear focal point (bearish signal in August); price line visually dominant through line weight; smooth EMA lines contrast nicely with jagged price. Visual hierarchy guides the reader

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) — EMA overlay line chart; price + two EMA series correctly displayed
  • SC-02: Required Features (4/4) — Price line prominent; two EMAs overlaid with distinct colors; EMA lines thinner than price; legend with period labels; crossover points highlighted with directional markers
  • SC-03: Data Mapping (3/3) — Date on X, Price (USD) on Y; all 150 trading days shown; axes span full data range
  • SC-04: Title & Legend (3/3) — Title indicator-ema · python · seaborn · anyplot.ai exact format; legend labels "Close Price", "EMA 12", "EMA 26"

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) — Shows all aspects: jagged close price, short-period EMA (12), long-period EMA (26), trending period (decline → recovery), bullish/bearish crossover signals, 150 trading days
  • DQ-02: Realistic Context (5/5) — Stock price scenario with standard technical indicators; 2024 trading calendar; neutral finance domain; no controversial content
  • DQ-03: Appropriate Scale (4/4) — ~$155–$225 price range plausible for mid-cap stock; 2.5% daily volatility elevated but individually realistic; EMA calculation via pandas ewm(span=…, adjust=False) is mathematically correct

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3) — Flat script: Imports → Theme tokens → Data → Plot → Style → Save; no functions or classes
  • CQ-02: Reproducibility (2/2) — np.random.seed(42) set before data generation
  • CQ-03: Clean Imports (2/2) — os, matplotlib.pyplot, numpy, pandas, seaborn — all used
  • CQ-04: Code Elegance (2/2) — Idiomatic pandas ewm for EMA; crossover detection with shift; clean melt for long format; no over-engineering
  • CQ-05: Output & API (1/1) — Saves as plot-{THEME}.png; no deprecated seaborn/matplotlib API

Library Mastery (8/10)

  • LM-01: Idiomatic Usage (5/5) — Long-format DataFrame via pd.melt; sns.lineplot with hue, hue_order, and explicit palette dict; sns.set_theme with rc={} for full theme control — textbook idiomatic seaborn
  • LM-02: Distinctive Features (3/5) — Hue-based multi-series with an explicit palette dict is a seaborn-distinctive pattern. However, crossover markers (ax.scatter) and line-width adjustment (ax.get_lines()) are implemented at the matplotlib layer; a more seaborn-native enhancement (e.g. sns.scatterplot with the same DataFrame, or a rugplot layer) would score higher

Score Caps Applied

  • None — no caps triggered (DE-01=5>2, DE-02=5>2; no zero-scored VQ/SC/DQ criteria)

Strengths

  • Correct Okabe-Ito palette with perfect canonical ordering and fully theme-adaptive chrome in both renders
  • All font sizes explicitly set and verified readable in light and dark themes
  • Crossover markers (bullish/bearish triangles) add meaningful information and create visual focal points aligned with the spec request
  • Idiomatic seaborn usage: long-format melt + hue grouping + palette dict is the recommended seaborn pattern for multi-series lines
  • Mathematically correct EMA computation (ewm(span=…, adjust=False)) with reproducible synthetic data

Weaknesses

  • DE-01: Lacks visual depth features such as a shaded region between EMA lines or background trend bands that would elevate the design from "competent" to "publication-ready"
  • LM-02: Crossover markers and line-width adjustments drop to matplotlib primitives; wrapping crossover data into the long DataFrame and using sns.scatterplot would keep more logic at the seaborn layer

Issues Found

  1. DE-01 BELOW MAX (5/8): Design is clean but lacks visual depth — no fill between EMA lines, no shaded trend-period bands, no annotation for the key bearish crossover signal
    • Fix: Add ax.fill_between between EMA 12 and EMA 26 with low alpha (0.15) to highlight divergence/convergence zones
  2. LM-02 AVERAGE (3/5): Crossover marker additions use ax.scatter (matplotlib primitive) rather than seaborn's API
    • Fix: Add crossover points to the long DataFrame and render them via sns.scatterplot on the same axes, keeping the implementation seaborn-idiomatic

AI Feedback for Next Attempt

The implementation is solid: correct palette, clean theming, idiomatic seaborn, full spec compliance. To push beyond 90, add ax.fill_between shading between EMA 12 and EMA 26 lines (alpha ~0.15) — green when EMA 12 > EMA 26 (bullish zone), vermillion when EMA 12 < EMA 26 (bearish zone). This single change improves DE-01, DE-03, and makes LM-02 more distinctive. Optionally route crossover markers through sns.scatterplot to stay idiomatic.

Verdict: APPROVED

@github-actions github-actions Bot added quality:90 Quality score 90/100 ai-approved Quality OK, ready for merge and removed quality:88 Quality score: 88/100 labels May 19, 2026
@MarkusNeusinger MarkusNeusinger merged commit 07bf11d into main May 19, 2026
3 checks passed
@MarkusNeusinger MarkusNeusinger deleted the implementation/indicator-ema/seaborn branch May 19, 2026 05:08
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:90 Quality score 90/100

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant