Skip to content

feat(plotly): implement streamgraph-basic#5699

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

feat(plotly): implement streamgraph-basic#5699
MarkusNeusinger merged 4 commits intomainfrom
implementation/streamgraph-basic/plotly

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

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

Implementation: streamgraph-basic - python/plotly

Implements the python/plotly version of streamgraph-basic.

File: plots/streamgraph-basic/implementations/python/plotly.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 plot renders on a warm off-white background (#FAF8F1). Six smooth, flowing stream bands span January 2022 through December 2023: Pop (teal-green #009E73), Rock (vermillion #D55E00), Hip-Hop (blue #0072B2), Electronic (reddish-purple #CC79A7), Jazz (orange #E69F00), Classical (sky-blue #56B4E9). The centered baseline creates a symmetric river shape with streams above and below zero. Title "streamgraph-basic · plotly · anyplot.ai" is large and centered. A horizontal legend sits just above the plot. Y-axis label reads "Streaming Hours (Millions)"; X-axis label reads "Month". All text is clearly readable against the light background — title, axis labels, and tick labels are all dark-on-light with no legibility issues.

Dark render (plot-dark.png): The plot renders on a warm near-black background (#1A1A17). The data colors are identical to the light render — same green, orange, blue, pink, yellow, sky-blue in the same order. All chrome flips correctly: title is light (#F0EFE8), axis labels are light, tick labels are lighter gray (#B8B7B0), legend box uses the elevated dark surface (#242420). No dark-on-dark failures detected — all text is clearly readable against the near-black background. The zero line and y-axis grid are rendered with the correct low-opacity light rule color.

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

Score: 88/100

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

Visual Quality (29/30)

  • VQ-01: Text Legibility (8/8) — All font sizes explicitly set: title 28px, axis labels 22px, ticks 18px, legend 18px. Readable in both themes.
  • VQ-02: No Overlap (6/6) — No overlapping text or elements.
  • VQ-03: Element Visibility (6/6) — All six stream bands clearly visible, well-differentiated, smooth curves.
  • VQ-04: Color Accessibility (2/2) — Okabe-Ito is CVD-safe; adjacent streams have good luminance contrast.
  • VQ-05: Layout & Canvas (4/4) — Plot fills the canvas well with balanced margins; legend does not overlap data.
  • VQ-06: Axis Labels & Title (1/2) — Labels have units but the centered-baseline Y-axis shows negative values (e.g., −100) for "Streaming Hours (Millions)"; negative streaming hours are physically meaningless. The label is descriptive but confusing in context. Consider hiding Y-axis labels or relabeling them to reflect the centered layout.
  • VQ-07: Palette Compliance (2/2) — First series is #009E73, multi-series follows Okabe-Ito canonical order exactly. Backgrounds are #FAF8F1 (light) / #1A1A17 (dark). Theme-adaptive chrome is correct in both renders.

Design Excellence (12/20)

  • DE-01: Aesthetic Sophistication (5/8) — Clean palette, intentional font hierarchy, and theme-adaptive chrome lift this above defaults. The streamgraph form itself provides organic visual interest. Falls short of FiveThirtyEight-level polish — no deliberate emphasis, typography variation, or accent elements.
  • DE-02: Visual Refinement (4/6) — Y-axis-only grid with subtle low-opacity rule color is well-judged. Zero line shown appropriately. However, top and right spines are not removed; generous margins are a plus. Some detail refinement is present but not fully polished.
  • DE-03: Data Storytelling (3/6) — The streamgraph form inherently suggests relative proportions (Pop dominates the bottom band). But there is no intentional visual hierarchy, annotation, or emphasis to guide the viewer to a specific insight. Data is shown, not interpreted.

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) — Correct streamgraph with centered symmetric baseline.
  • SC-02: Required Features (4/4) — Smooth spline interpolation, centered baseline, distinct harmonious colors, legend all present.
  • SC-03: Data Mapping (3/3) — Time on X, streamed values on Y, all 24 months and 6 genres visible.
  • SC-04: Title & Legend (3/3) — Title is "streamgraph-basic · plotly · anyplot.ai". Legend labels match genre names exactly.

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) — Shows 6 genres with varying magnitudes, temporal trends, and seasonality — all aspects of the plot type are demonstrated.
  • DQ-02: Realistic Context (5/5) — Monthly streaming hours by music genre: neutral, real-world, comprehensible scenario.
  • DQ-03: Appropriate Scale (4/4) — Base values (Pop=45M, Rock=35M, Hip-Hop=40M, etc.) are plausible for a medium-sized music streaming service.

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3) — Imports → Data → Streamgraph calculation → Plot → Save. No functions or classes.
  • CQ-02: Reproducibility (2/2) — np.random.seed(42) set.
  • CQ-03: Clean Imports (2/2) — Only sys, os, numpy, pandas, and plotly.graph_objects imported; all are used.
  • CQ-04: Code Elegance (2/2) — Clean and Pythonic. The cumulative-sum centering computation is correct and concise.
  • CQ-05: Output & API (1/1) — Saves plot-{THEME}.png and plot-{THEME}.html using current API.

Library Mastery (7/10)

  • LM-01: Idiomatic Usage (4/5) — go.Scatter with fill="toself", shape="spline", hoveron="fills", and hovermode="x unified" is the correct idiomatic Plotly approach for a streamgraph. Slightly below perfect — could leverage update_layout defaults more cleanly.
  • LM-02: Distinctive Features (3/5) — Interactive hover on fill areas (hoveron="fills"), unified x hover mode, and HTML export are genuinely Plotly-distinctive features. Spline boundary smoothing through the line shape parameter is also Plotly-specific.

Score Caps Applied

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

Strengths

  • Perfect palette compliance: Okabe-Ito in canonical order, correct first-series green #009E73, theme-adaptive chrome working correctly in both renders.
  • All font sizes explicitly set per style guide; fully readable in both light and dark themes.
  • Correct streamgraph mechanics: cumulative-sum centering, spline smoothing, fill boundary calculation.
  • Full spec compliance: all required features present.
  • Idiomatic Plotly use of hoveron="fills" and hovermode="x unified" enabling rich interactivity in the HTML output.

Weaknesses

  • Y-axis label "Streaming Hours (Millions)" with negative tick values is confusing — the centered-baseline offset makes streaming hours appear negative, which is physically meaningless. Remove or hide Y-axis tick labels, or relabel to something like "← Centered offset →" or simply omit the Y-axis to keep focus on stream widths.
  • Top and right spines not removed — the plot still shows a full four-sided frame, which adds unnecessary chrome.
  • No visual hierarchy or emphasis: all streams are weighted equally. Subtle visual emphasis (e.g., slightly higher opacity or slightly thicker border on the dominant stream) could guide the viewer.
  • DE-01 does not reach strong design: no typography weight variation, no accent callout, no intentional focal point.

Issues Found

  1. VQ-06 MINOR: Y-axis labels show negative streaming hours (e.g., −100M) due to centered baseline offset.
    • Fix: Either hide the y-axis entirely (showticklabels=False, showgrid=False, remove y-axis title`) to focus on stream widths, or keep a minimal zero line with no tick labels.
  2. DE-02 MODERATE: Top and right spines remain visible.
    • Fix: Add showline=False / remove frame lines, or set xaxis.showline=False and remove the outer border to produce an L-frame or frameless look.
  3. DE-01/DE-03 MODERATE: No visual emphasis or hierarchy beyond equal-weight stream bands.
    • Fix: Increase fillcolor opacity/saturation for the dominant stream (Pop), or add a subtle opacity=0.85 on non-dominant streams to let the largest band read more strongly.

AI Feedback for Next Attempt

Three focused improvements: (1) Remove or hide the Y-axis tick labels and title — the centered streamgraph baseline makes streaming-hour values meaningless as absolute numbers; just keep the zero line for reference. (2) Remove top and right spines (xaxis.showline=False, yaxis.showline=False, or set fig.update_layout(xaxis_showline=False, yaxis_showline=False)) for a cleaner frameless or L-frame look. (3) Add subtle visual hierarchy — e.g., reduce opacity to 0.80–0.85 on all non-dominant streams while keeping Pop at full opacity, or add a faint line.width=1 border on the dominant stream. These three changes address DE-01, DE-02, and DE-03 without altering the correct palette, theme chrome, or spec compliance.

Verdict: REJECTED

@github-actions github-actions Bot added quality:88 Quality score: 88/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
Attempt 1/3 - fixes based on AI review
@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 plot renders on a warm off-white #FAF8F1 background. The title "streamgraph-basic · plotly · anyplot.ai" appears in dark ink (#1A1A17) at 28px, and the subtitle "Monthly streaming hours by music genre, 2022–2023" is rendered below it in a smaller, muted secondary text color. Six flowing streams are stacked and centered symmetrically around the zero line, spanning Jan 2022 to Oct 2023. From bottom to top the colors are: green (Pop, #009E73), orange-red (Rock, #D55E00), blue (Hip-Hop, #0072B2), pink-purple (Electronic, #CC79A7), yellow-orange (Jazz, #E69F00), and sky blue (Classical, #56B4E9). All streams use smooth spline curves giving an organic, river-like appearance. A horizontal legend sits below the chart with colored swatches and genre labels. The x-axis shows month tick labels (Jan 2022, Apr 2022, …, Oct 2023) and a bottom-only spine. The y-axis has no tick labels (intentionally hidden), a subtle grid, and a thin zero line. All text is clearly readable against the light background with no legibility issues.

Dark render (plot-dark.png): The same chart on a warm near-black #1A1A17 background. The title, subtitle, axis labels, tick labels, and legend text all flip to light colors (near-white/warm gray), confirming correct theme adaptation. The six data stream colors are identical to the light render — green, orange-red, blue, pink-purple, yellow-orange, sky blue — as required (only chrome flips). The zero line and subtle grid remain visible against the dark background. The legend has a dark elevated background (#242420) with a light border. No dark-on-dark failures observed: all text elements are clearly readable against the near-black surface.

Both renders pass the theme-readability check.

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) — Title 28px, axis labels 22px, tick labels 18px; all elements clearly readable in both themes
  • VQ-02: No Overlap (6/6) — Streams, legend items, and tick labels all non-overlapping
  • VQ-03: Element Visibility (6/6) — All 6 genre streams are clearly distinct and visible across both themes
  • VQ-04: Color Accessibility (2/2) — Okabe-Ito palette used; CVD-safe by design
  • VQ-05: Layout & Canvas (4/4) — Good 16:9 proportions, generous margins, legend well-placed below
  • VQ-06: Axis Labels & Title (2/2) — "Month" x-axis label present; y-axis labels intentionally hidden for streamgraph clarity
  • VQ-07: Palette Compliance (2/2) — First series (Pop) = #009E73 ✓; Okabe-Ito order maintained; backgrounds #FAF8F1/#1A1A17 correct

Design Excellence (11/20)

  • DE-01: Aesthetic Sophistication (5/8) — Uses opacity hierarchy (Pop at 1.0, others at 0.80), smooth splines, zero-line anchor, horizontal bottom legend, and subtitle typography. Thoughtful above defaults but opacity difference is subtle (20%) and barely perceptible in the final render.
  • DE-02: Visual Refinement (3/6) — Bottom-only x spine, y-axis spine removed, y-tick labels hidden, subtle adaptive grid. Clean composition overall. Grid opacity could be further refined; zero line width is standard.
  • DE-03: Data Storytelling (3/6) — The centered baseline and smooth curves correctly communicate relative proportions and flow. The subtle Pop emphasis is there but not strong enough to create a clear focal point or narrative emphasis.

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) — Correct streamgraph with symmetric centered baseline using cumsum offset
  • SC-02: Required Features (4/4) — Smooth spline interpolation ✓, centered baseline ✓, distinct harmonious colors ✓, legend ✓
  • SC-03: Data Mapping (3/3) — X = time (months), Y = centered stacked values, all 6 categories present
  • SC-04: Title & Legend (3/3) — Title "streamgraph-basic · plotly · anyplot.ai" ✓; legend labels match genre names ✓

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) — Demonstrates all core streamgraph aspects: stacking, centering, smooth flow, multi-category composition
  • DQ-02: Realistic Context (5/5) — Music genre streaming hours is a well-known, neutral, real-world use case for streamgraphs
  • DQ-03: Appropriate Scale (4/4) — 24 time points (2 years monthly), 6 genres (within 3–8 spec), base values 12–45 hrs plausible

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3) — No functions or classes; flat, readable linear script
  • CQ-02: Reproducibility (2/2) — set before data generation
  • CQ-03: Clean Imports (2/2) — sys, os, numpy, pandas, plotly.graph_objects — all used
  • CQ-04: Code Elegance (2/2) — Clean iteration over genres, appropriate numpy vectorization for baseline computation
  • CQ-05: Output & API (1/1) — Saves (width=1600, height=900, scale=3 → 4800×2700) and ✓

Library Mastery (7/10)

  • LM-01: Idiomatic Usage (4/5) — Uses with , for smooth boundaries, , — all idiomatic Plotly patterns for area charts
  • LM-02: Distinctive Features (3/5) — Leverages Plotly's interactive hover on area fills and HTML export. Could further exploit Plotly's hover customization (e.g. custom showing percentage share or formatted hours), which would better demonstrate Plotly's interactivity advantage over static libraries.

Score Caps Applied

  • None

Strengths

  • Perfect spec compliance — streamgraph with centered baseline, smooth splines, correct data mapping
  • Flawless theme adaptation: all chrome tokens (INK, INK_SOFT, GRID, PAGE_BG, ELEVATED_BG) correctly applied in both themes
  • Excellent code quality: clean, flat, reproducible, idiomatic Plotly
  • Correct Okabe-Ito order starting with #009E73 for Pop
  • Appropriate use of Plotly-specific features: fill-hover interaction and HTML export

Weaknesses

  • DE-01: Opacity-based visual hierarchy (1.0 vs 0.80) is too subtle to create a perceptible focal point; a stronger emphasis technique (e.g. brightening the dominant stream or muting non-dominant ones further) would improve storytelling
  • DE-03: No clear narrative focal point or annotation to guide the viewer's eye; the plot is informative but doesn't tell a story
  • LM-02: is not customized — default tooltip format misses an opportunity to show formatted hours or genre share percentage

Issues Found

  1. DE-01 MODERATE: Opacity gap between Pop (1.0) and others (0.80) produces only a subtle difference. Fix: Increase the contrast — e.g., dominant stream at 1.0, others at 0.65, or use a slightly desaturated palette for secondary streams.
  2. DE-03 LOW: No storytelling emphasis. Fix: Add a brief annotation for an interesting trend point, or select data that shows a more dramatic evolution to make the "flow" more narratively compelling.

AI Feedback for Next Attempt

The implementation is technically solid — spec compliance and code quality are perfect. Focus improvements on design excellence: (1) increase the opacity gap between the focal stream (Pop) and secondary streams from 0.20 to at least 0.35 for perceptible visual hierarchy; (2) add a showing formatted hours (e.g. %{fullData.name}: %{customdata:.0f} hrs) to showcase Plotly's interactive advantage; (3) consider a subtle annotation marking a notable peak to create a clear focal point.

Verdict: APPROVED

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant