Skip to content

feat(matplotlib): implement streamgraph-basic#5697

Merged
MarkusNeusinger merged 5 commits intomainfrom
implementation/streamgraph-basic/matplotlib
May 5, 2026
Merged

feat(matplotlib): implement streamgraph-basic#5697
MarkusNeusinger merged 5 commits intomainfrom
implementation/streamgraph-basic/matplotlib

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot commented May 5, 2026

Implementation: streamgraph-basic - python/matplotlib

Implements the python/matplotlib version of streamgraph-basic.

File: plots/streamgraph-basic/implementations/python/matplotlib.py

Parent Issue: #856


🤖 impl-generate workflow

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented May 5, 2026

AI Review - Attempt 1/3

Image Description

Light render (plot-light.png): The streamgraph renders on a warm off-white background (approx. #FAF8F1), with six flowing color bands representing music genres over a 24-month period (Jan 2023 – Dec 2024). The dominant bottom band (Pop) appears in teal/green, followed by orange (Rock), dark blue (Hip-Hop), pink/mauve (Electronic), yellow-gold (Jazz), and sky blue (Classical) at the top. The title 'streamgraph-basic · matplotlib · anyplot.ai' is clearly visible in dark text. X-axis tick labels (quarterly) and the label 'Month (Jan 2023 – Dec 2024)' are legible. A legend sits in the upper right. All text is readable against the light background. However: the rendered images appear to be from a prior code version — the current code uses #306998 (Python Blue) as the first color, saves to plot.png (not plot-{THEME}.png), and titles the plot pyplots.ai — none of which match these images.

Dark render (plot-dark.png): The same chart on a near-black background (approx. #1A1A17). Data colors are identical to the light render (only the background and chrome flip). The title, axis labels, and tick labels appear in light text. No 'dark-on-dark' text failures visible. The legend frame is dark. All text is readable against the dark background. Note: The current code lacks any os.getenv('ANYPLOT_THEME') logic, so running it would produce a matplotlib-default white background for both renders — these dark-mode images are inconsistent with the code as submitted.

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

Score: 77/100

Category Score Max
Visual Quality 25 30
Design Excellence 10 20
Spec Compliance 12 15
Data Quality 14 15
Code Quality 9 10
Library Mastery 7 10
Total 77 100

Visual Quality (25/30)

  • VQ-01: Text Legibility (7/8) — Font sizes explicitly set (title 24pt, xlabel 20pt, ticks 16pt, legend 16pt). All text readable in both renders.
  • VQ-02: No Overlap (6/6) — Quarterly x-axis ticks spaced well, no collisions.
  • VQ-03: Element Visibility (6/6) — Stream bands clearly visible and well-proportioned.
  • VQ-04: Color Accessibility (1/2) — The code uses a custom non-Okabe-Ito palette; CVD safety of #306998, #FFD43B, #3D405B etc. is not guaranteed.
  • VQ-05: Layout & Canvas (3/4) — Good canvas utilization; legend slightly pushes into upper data area.
  • VQ-06: Axis Labels & Title (2/2) — Images show 'Month (Jan 2023 – Dec 2024)'; descriptive.
  • VQ-07: Palette Compliance (0/2) — FAIL: Code explicitly uses #306998 (Python Blue) as first series color — this is the legacy Python Blue, explicitly listed as disqualifying in VQ-07. First series must be #009E73 (Okabe-Ito position 1). Additionally, the implementation has zero theme-adaptation logic (os.getenv missing entirely), so a dark-mode run would produce a white matplotlib default background.

Design Excellence (10/20)

  • DE-01: Aesthetic Sophistication (4/8) — Streamgraph shape is appealing and clean, but no exceptional design choices beyond the basic implementation. Good proportions but not publication-level polish.
  • DE-02: Visual Refinement (4/6) — Three spines removed (top, right, left), y-axis ticks suppressed (appropriate for streamgraph), no distracting grid. Solid refinement.
  • DE-03: Data Storytelling (2/6) — Data is displayed clearly and the growth/seasonal trends are implied, but no visual hierarchy, emphasis, or focal point. Viewer must find their own story.

Spec Compliance (12/15)

  • SC-01: Plot Type (5/5) — Correct streamgraph using ax.stackplot(..., baseline='wiggle').
  • SC-02: Required Features (3/4) — Streamgraph with symmetric baseline ✓, distinct colors ✓, legend ✓. Missing: spec calls for smooth spline/basis interpolation; stackplot uses piecewise-linear interpolation between data points, which is not truly smooth.
  • SC-03: Data Mapping (3/3) — Time on X, stacked values on Y, all 6 categories mapped correctly.
  • SC-04: Title & Legend (1/3) — Legend labels are correct. Title FAIL: code produces 'streamgraph-basic · matplotlib · pyplots.ai' — brand name must be anyplot.ai, not pyplots.ai.

Data Quality (14/15)

  • DQ-01: Feature Coverage (5/6) — Six genres with diverse trend patterns: Pop dominant/steady-growth, Hip-Hop rising, Jazz declining, Electronic seasonal, Rock seasonal, Classical winter-peaks. Good variety.
  • DQ-02: Realistic Context (5/5) — Monthly streaming hours by music genre, 2023–2024. Neutral, comprehensible, real-world scenario.
  • DQ-03: Appropriate Scale (4/4) — Values ~5–80 hours/month per genre, realistic proportions, trends align with plausible real-world behavior.

Code Quality (9/10)

  • CQ-01: KISS Structure (3/3) — Clean flat structure: imports → data → plot → save.
  • CQ-02: Reproducibility (2/2) — np.random.seed(42) set.
  • CQ-03: Clean Imports (2/2) — Only matplotlib.pyplot and numpy imported, both used.
  • CQ-04: Code Elegance (2/2) — Pythonic, no over-engineering, no fake UI.
  • CQ-05: Output & API (0/1) — FAIL: Saves to plot.png instead of plot-{THEME}.png. Per library spec, output must be plt.savefig(f'plot-{THEME}.png', ...).

Library Mastery (7/10)

  • LM-01: Idiomatic Usage (4/5) — Uses ax.stackplot with Axes methods (not pyplot), tight_layout(), correct figsize. Solid idiomatic usage.
  • LM-02: Distinctive Features (3/5) — baseline='wiggle' is the matplotlib-specific streamgraph feature, a good use of a library-distinctive parameter.

Score Caps Applied

  • None applied (DE-01=4 > 2, DE-02=4 > 2; no 75-cap triggered).

Strengths

  • Streamgraph chart type correctly implemented with baseline='wiggle' for organic flow
  • Good data: diverse genre trends show seasonal, growing, and declining patterns
  • Clean code structure with explicit font sizes and appropriate spine removal
  • Y-axis ticks correctly suppressed (appropriate for streamgraph where absolute values are secondary)

Weaknesses

  • Critical: First series color is #306998 (Python Blue) — must be replaced with Okabe-Ito palette starting at #009E73
  • Critical: No os.getenv('ANYPLOT_THEME') theme adaptation — both light and dark renders will use matplotlib's default white background; must read ANYPLOT_THEME and apply PAGE_BG, INK, INK_SOFT, legend frame colors
  • Critical: Title uses pyplots.ai instead of anyplot.ai
  • Critical: Output file saved as plot.png — must be plot-{THEME}.png
  • No smooth spline interpolation — spec requests spline/basis curves; consider scipy.interpolate for true smooth curves

Issues Found

  1. VQ-07 ZERO / CQ-05 ZERO: Four critical compliance failures — wrong palette, no theme adaptation, wrong brand name, wrong output filename
    • Fix: Add import os; THEME = os.getenv('ANYPLOT_THEME', 'light'), derive PAGE_BG/INK/INK_SOFT tokens, apply to fig/ax/legend/ticks; replace colors list with Okabe-Ito; change title to anyplot.ai; change savefig to f'plot-{THEME}.png'
  2. SC-04 FAIL: Brand name mismatch
    • Fix: ax.set_title('streamgraph-basic · matplotlib · anyplot.ai', fontsize=24, color=INK)
  3. DE-03 LOW: No visual hierarchy or storytelling
    • Fix: Consider highlighting the dominant trend (Pop's growth or Hip-Hop's rise) with stronger color saturation, or adding a subtle annotation pointing to a key trend inflection

AI Feedback for Next Attempt

Must fix (blockers): (1) Replace colors = ['#306998', ...] with Okabe-Ito: ['#009E73', '#D55E00', '#0072B2', '#CC79A7', '#E69F00', '#56B4E9']. (2) Add full theme-adaptive chrome: read ANYPLOT_THEME env var, set PAGE_BG, INK, INK_SOFT tokens, apply to fig.set_facecolor, ax.set_facecolor, title color, xlabel color, tick_params, legend frame. (3) Fix title to anyplot.ai. (4) Fix savefig to f'plot-{THEME}.png'. Optional improvement: Use scipy.interpolate to generate smooth spline curves between monthly data points before passing to stackplot, for true organic streamgraph curves as specified.

Verdict: REJECTED

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

github-actions Bot commented May 5, 2026

🔧 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 5, 2026

AI Review - Attempt 2/3

Image Description

Light render (plot-light.png): The streamgraph renders on a warm off-white #FAF8F1 background with 6 smooth, flowing bands in Okabe-Ito canonical order: #009E73 (Pop, bottom/largest band), #D55E00 (Rock, orange), #0072B2 (Hip-Hop, dark blue, visibly growing toward the right), #CC79A7 (Electronic, pink), #E69F00 (Jazz, gold), and #56B4E9 (Classical, sky blue at top). Alpha=0.85 gives slight translucency. The title "streamgraph-basic · matplotlib · anyplot.ai" appears in dark ink at top, x-axis label "Month (Jan 2023 – Dec 2024)" at bottom, and tick labels (Jan'23 through Oct'24 at 3-month intervals) in muted dark tone. A legend with elevated off-white frame sits in the upper-left. All text is clearly readable against the light background.

Dark render (plot-dark.png): The same streamgraph renders on a near-black #1A1A17 background. Data band colors are identical to the light render — only chrome flips. Title and x-axis label appear in light ink (#F0EFE8), tick labels in lighter muted tone (#B8B7B0). The legend uses a dark elevated frame (#242420) with light-colored text. No dark-on-dark failures observed — all text is clearly readable against the near-black background. The symmetric wiggle baseline creates a small dark "floor" at the bottom which correctly shows the page background through.

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 11 20
Spec Compliance 15 15
Data Quality 15 15
Code Quality 10 10
Library Mastery 7 10
Total 88 100

Visual Quality (30/30)

  • VQ-01: Text Legibility (8/8) — All font sizes explicitly set (title=24, xlabel=20, ticks=16, legend=16). Readable in both themes.
  • VQ-02: No Overlap (6/6) — No overlapping text. X-axis labels spaced every 3 months. Legend does not obscure critical data.
  • VQ-03: Element Visibility (6/6) — Stream bands clearly visible and well-proportioned. Alpha=0.85 adds depth.
  • VQ-04: Color Accessibility (2/2) — Okabe-Ito palette is CVD-safe. Adjacent bands have sufficient luminance contrast.
  • VQ-05: Layout & Canvas (4/4) — Streamgraph fills canvas well with balanced margins.
  • VQ-06: Axis Labels & Title (2/2) — "Month (Jan 2023 – Dec 2024)" is descriptive. Y-axis correctly hidden for streamgraph.
  • VQ-07: Palette Compliance (2/2) — First series #009E73, all 6 follow Okabe-Ito order, backgrounds #FAF8F1/#1A1A17, chrome correct in both themes.

Design Excellence (11/20)

  • DE-01: Aesthetic Sophistication (5/8) — Above well-configured default: smooth spline curves, alpha blending, clean spine removal create genuine polish. Not quite "strong design" — no distinctive typographic choices or focal-point emphasis.
  • DE-02: Visual Refinement (4/6) — Good refinement: all spines removed except bottom, y-axis hidden, no grid, legend frame styled with elevated background and INK_SOFT border.
  • DE-03: Data Storytelling (2/6) — Data displayed without visual hierarchy or emphasis. The Hip-Hop growth trend is an interesting story but nothing guides the viewer toward it.

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) — Correct streamgraph: ax.stackplot with baseline='wiggle' creates symmetric centered baseline. Cubic spline interpolation creates flowing curves.
  • SC-02: Required Features (4/4) — All spec features present: smooth interpolation, symmetric baseline, distinct harmonious colors, legend, 6 categories, 24 time points.
  • SC-03: Data Mapping (3/3) — Time on X-axis across Jan 2023–Dec 2024, all 6 genre streams stacked, all data visible.
  • SC-04: Title & Legend (3/3) — Title "streamgraph-basic · matplotlib · anyplot.ai" correct. Legend labels match all 6 category names.

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) — Shows full range: growing trends (Hip-Hop, Pop), declining trends (Jazz, Classical), oscillating (Rock, Electronic). Demonstrates streamgraph composition well.
  • DQ-02: Realistic Context (5/5) — Music streaming hours by genre is highly realistic, neutral, and comprehensible. Named genres, 2023–2024 timeframe. No controversial content.
  • DQ-03: Appropriate Scale (4/4) — Values 15–100 hours/month are plausible. Pop as largest, Hip-Hop growing, Jazz/Classical declining — all realistic market trends.

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3) — No functions or classes. Clean Imports → Data → Plot → Save flow.
  • CQ-02: Reproducibility (2/2) — np.random.seed(42) set.
  • CQ-03: Clean Imports (2/2) — os, matplotlib.pyplot, numpy, scipy.interpolate.make_interp_spline — all used.
  • CQ-04: Code Elegance (2/2) — Clean, Pythonic. List comprehension for smooth data array. No fake UI.
  • CQ-05: Output & API (1/1) — Saves as plot-{THEME}.png with dpi=300, bbox_inches='tight'. Current API.

Library Mastery (7/10)

  • LM-01: Idiomatic Usage (4/5) — Uses ax.stackplot() with baseline='wiggle' — the recommended matplotlib approach for streamgraphs. Axes methods throughout, plt.setp() for legend text.
  • LM-02: Distinctive Features (3/5) — baseline='wiggle' in stackplot is matplotlib-specific and creates the streamgraph effect. Smooth curves rely on scipy preprocessing rather than any matplotlib-native smoothing technique.

Score Caps Applied

  • None — DE-01=5 and DE-02=4, both above the ≤2 threshold; no cap triggered.

Strengths

  • Correct streamgraph using ax.stackplot with baseline='wiggle' — the idiomatic matplotlib approach for this chart type
  • Smooth cubic spline interpolation via scipy creates genuinely flowing, organic curves matching the spec's requirement
  • Full Okabe-Ito palette compliance: #009E73 as first series, all 6 in canonical order
  • Both light and dark themes implemented correctly with all chrome tokens properly applied throughout
  • Perfect spec compliance: symmetric baseline, smooth curves, distinct colors, legend, realistic music streaming data
  • Clean KISS code with seed, explicit font sizes (24/20/16), and all-used imports

Weaknesses

  • Design storytelling is absent — no visual hierarchy or emphasis to guide the viewer toward any insight (DE-03 = 2/6)
  • Aesthetic sophistication is at the well-configured-default level — no distinctive typographic choices or focal-point elements to elevate the design (DE-01 = 5/8)
  • Library mastery could be stronger — smooth curves rely on scipy preprocessing rather than any matplotlib-native curve-smoothing (LM-02 = 3/5)

Issues Found

  1. DE-03 LOW: No visual hierarchy or storytelling — the Hip-Hop growth trend is interesting but nothing guides the viewer toward it
    • Fix: Add subtle emphasis — e.g., slightly higher alpha or a thin outline on the fastest-growing band, or a minimalist annotation marking the trend
  2. DE-01 MODERATE: Design is polished but not distinctive
    • Fix: Consider a refined title with subtitle for context, or use slight stroke on stream boundaries for better definition between adjacent similarly-valued bands

AI Feedback for Next Attempt

The implementation is technically excellent and scores perfectly on spec compliance, data quality, and code quality. The main gap is design storytelling (DE-03): add visual hierarchy to guide the viewer — e.g., a subtle outline or slightly boosted alpha on the most interesting band (Hip-Hop growth), or a minimalist annotation. Also consider minor DE-01 improvements: a descriptive subtitle or refined legend placement. Do not change the palette, theme tokens, or overall structure — those are correct.

Verdict: APPROVED

@github-actions github-actions Bot added quality:88 Quality score: 88/100 ai-approved Quality OK, ready for merge labels May 5, 2026
@MarkusNeusinger MarkusNeusinger merged commit d7f30db into main May 5, 2026
3 checks passed
@MarkusNeusinger MarkusNeusinger deleted the implementation/streamgraph-basic/matplotlib branch May 5, 2026 03:41
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:77 Quality score 77/100 quality:88 Quality score: 88/100

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant