Skip to content

feat(ggplot2): implement piano-roll-midi#8309

Merged
MarkusNeusinger merged 6 commits into
mainfrom
implementation/piano-roll-midi/ggplot2
Jun 3, 2026
Merged

feat(ggplot2): implement piano-roll-midi#8309
MarkusNeusinger merged 6 commits into
mainfrom
implementation/piano-roll-midi/ggplot2

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot commented Jun 3, 2026

Implementation: piano-roll-midi - r/ggplot2

Implements the r/ggplot2 version of piano-roll-midi.

File: plots/piano-roll-midi/implementations/r/ggplot2.R

Parent Issue: #4565


🤖 impl-generate workflow

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Jun 3, 2026

AI Review - Attempt 1/3

Image Description

Light render (plot-light.png): The piano roll renders on a warm off-white (#FAF8F1) background. Piano keyboard row alternation is clearly visible — white key rows are slightly lighter beige (#EBE7DC), black key rows slightly darker (#D3CDB8). The right-hand melody notes appear as near-square green-to-teal rectangles (quiet, velocity ~55–80) in the C4–G5 range, building to deeper teal/blue in the climax measures. Left-hand bass notes (C3, F3, A3, G3 rows) appear as longer teal rectangles at moderate velocity. Measure boundary vertical lines clearly delineate m1–m9 sections; beat subdivision lines are very faint. The velocity colorbar on the right uses musical dynamics labels (pp / p / mf / f / ff), which is a thoughtful domain-appropriate choice. Title, axis labels (Measure, Pitch), and tick labels (note names C3–G5 on Y, m1–m9 on X) are all clearly readable against the light background. All text passes legibility check. Legibility verdict: PASS

Dark render (plot-dark.png): The same piano roll on a warm near-black (#1A1A17) background. Keyboard row alternation is visible with dark-gray tones. Data colors (green→blue velocity gradient) are identical to the light render — only chrome flips. Title and axis labels render in near-white (#F0EFE8), tick labels in soft gray (#B8B7B0). The legend box has an elevated dark background (#242420) with a subtle border. Measure lines appear as faint-white vertical lines; beat subdivision lines are present but very subtle (which is intentional and correct). No dark-on-dark failure observed — all text is clearly readable against the dark surface. Legibility verdict: PASS

Both paragraphs confirmed. Both renders correctly implement theme-adaptive chrome with identical data colors.

Score: 86/100

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

Visual Quality (28/30)

  • VQ-01: Text Legibility (7/8) — All font sizes explicitly set (title=12, axis.title=10, axis.text=8, axis.text.y=7); well-proportioned. Minor: y-axis at size 7 is the minimum acceptable and may be small at mobile widths (~400 px).
  • VQ-02: No Overlap (6/6) — No overlapping text or data elements in either render.
  • VQ-03: Element Visibility (5/6) — Notes are clearly visible; right-hand melody notes are near-square (0.45 beat duration) rather than clearly horizontal, which is realistic for eighth notes but slightly reduces the characteristic piano-roll rectangle feel.
  • VQ-04: Color Accessibility (2/2) — Imprint seq colormap (green→blue) is CVD-safe; keyboard row contrast is adequate.
  • VQ-05: Layout & Canvas (4/4) — Plot fills the canvas well with balanced margins; legend is well-positioned.
  • VQ-06: Axis Labels & Title (2/2) — Measure and Pitch are descriptive for the domain.
  • VQ-07: Palette Compliance (2/2) — Velocity uses imprint_seq (CMAP_LOW=#009E73, CMAP_HIGH=#4467A3); backgrounds are #FAF8F1 (light) / #1A1A17 (dark); chrome is theme-correct in both renders.

Design Excellence (12/20)

  • DE-01: Aesthetic Sophistication (5/8) — Above generic defaults: piano keyboard background alternation, musical dynamics labels (pp/p/mf/f/ff) on the colorbar, and a clean velocity gradient create a polished domain-appropriate look. Doesn't quite reach publication-ready — no accent or focal-point emphasis at the dynamic climax.
  • DE-02: Visual Refinement (4/6) — Grid removed and replaced with deliberate beat/measure lines at two visual weights; legend is styled with elevated background and border; note rectangles have thin PAGE_BG borders for definition. All four panel borders retained, which is appropriate for an enclosed piano roll grid.
  • DE-03: Data Storytelling (3/6) — The velocity arc from mf→ff (climax at m6–m7)→p (resolution at m8) is visible in the color gradient, and the melodic ascent/descent pattern is spatially clear. Above the default of 2, but no explicit annotation or visual accent guides the viewer to the climax.

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) — Correct piano roll / DAW-style visualization with all required elements.
  • SC-02: Required Features (4/4) — Note names on Y-axis ✓, black/white key background alternation ✓, beat+measure grid lines with two visual weights ✓, sequential velocity colormap ✓, pitch range auto-fitted with 1-semitone margin ✓.
  • SC-03: Data Mapping (3/3) — X=start time in beats, Y=pitch (MIDI→note names), width=duration, fill=velocity. All correctly mapped.
  • SC-04: Title & Legend (3/3) — Title piano-roll-midi · r · ggplot2 · anyplot.ai is exactly correct. Velocity colorbar with pp/p/mf/f/ff labels is appropriate and domain-correct.

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) — Right-hand melody + left-hand bass, varying durations (0.45 vs 0.85 beats), dynamic arc (mf→ff→p), 3+ octave range, 96 total notes covering all aspects of the piano roll format.
  • DQ-02: Realistic Context (5/5) — 8-measure C-major piano piece with C–F–Am–G bass progression; realistic MIDI pitch numbers and velocity values.
  • DQ-03: Appropriate Scale (4/4) — MIDI pitches 48–79 (C3–G5, sensible piano range); velocities 30–127 (realistic dynamic arc); 32 beats / 4/4 time. All proportions factually correct.

Code Quality (9/10)

  • CQ-01: KISS Structure (2/3) — Two small helper functions (midi_to_name, is_black_key) deviate from the strict Imports→Data→Plot→Save pattern; however, both are compact (2–3 lines each) and genuinely useful for this plot type.
  • CQ-02: Reproducibility (2/2) — set.seed(42) present.
  • CQ-03: Clean Imports (2/2) — Only ggplot2 and ragg imported, both used.
  • CQ-04: Code Elegance (2/2) — Clean, idiomatic R; no over-engineering; no fake functionality.
  • CQ-05: Output & API (1/1) — Saves as plot-${THEME}.png via ragg; correct API usage.

Library Mastery (7/10)

  • LM-01: Idiomatic Usage (4/5) — Grammar-of-graphics layer composition is idiomatic: multiple geom_rect() layers with separate data frames for background and notes, scale_fill_gradient(), scale_x/y_continuous() with explicit breaks/labels, guides(fill=guide_colorbar()). Very clean ggplot2 usage.
  • LM-02: Distinctive Features (3/5) — Uses ggplot2's layered grammar to compose background rects + vlines + note rects from different data sources in a single plot — a distinctive ggplot2 strength. Could additionally leverage theme() to remove top/right panel border components distinctively, or use ggplot2's expansion() more creatively.

Score Caps Applied

  • None — no caps triggered (DE-01=5 and DE-02=4 are both above the ≤2 threshold for the "correct but boring" cap).

Strengths

  • Perfect spec compliance: all required piano roll features (keyboard background, note names, two-weight grid, velocity colormap, auto-fitted pitch range) are present and correct
  • Musical dynamics labels (pp/p/mf/f/ff) on the velocity colorbar — domain-appropriate and reader-friendly
  • Correct Imprint seq colormap (#009E73#4467A3) for velocity; both renders are fully theme-adaptive with no chrome failures
  • Rich, realistic musical data with a clear dynamic arc (mf→ff→p) that creates natural visual hierarchy through color
  • Clean idiomatic ggplot2 grammar-of-graphics composition with properly weighted beat/measure grid lines

Weaknesses

  • DE-03 could be lifted: the dynamic climax at m6–m7 is visible in color but not accented — a subtle annotation (e.g., a faint label "ff" or a translucent highlight bar at the climax measure boundary) would guide the viewer without cluttering the plot
  • Y-axis tick labels at size 7 are at the minimum acceptable threshold; bumping to 8 would improve mobile readability without disrupting layout
  • The two helper functions (midi_to_name, is_black_key) could be inlined as named vectors/logical masks for strict KISS compliance: e.g., note_names[(midi %% 12) + 1] directly and BLACK_KEYS <- c(1L, 3L, 6L, 8L, 10L); midi %% 12 %in% BLACK_KEYS

Issues Found

  1. DE-03 BELOW-POTENTIAL: Velocity arc story is latent in the color gradient but unexplained
    • Fix: Add a subtle translucent highlight or faint annotation near the climax beat (around x=20–24, the start of m6) to guide the viewer to the dynamic peak
  2. VQ-01 MINOR: Y-axis text at size 7 near mobile-readability floor
    • Fix: Increase axis.text.y from 7 to 8; the piano roll has enough vertical space

AI Feedback for Next Attempt

The implementation is technically strong and fully spec-compliant. To reach 90+: (1) Add a subtle visual accent at the dynamic climax — a faint translucent rectangle behind m6 or a small annotation like "climax" would lift DE-03 from 3 to 5 without cluttering the plot. (2) Increase axis.text.y from 7 to 8 for better mobile readability. (3) Optionally inline the two helper functions as named vectors for stricter KISS. The palette, theme-adaptation, data, and spec compliance are all excellent — only design storytelling holds this back from 90+.

Verdict: REJECTED

@github-actions github-actions Bot added quality:86 Quality score 86/100 ai-rejected Quality not OK, triggers update labels Jun 3, 2026
@github-actions github-actions Bot added ai-attempt-1 First repair attempt and removed ai-rejected Quality not OK, triggers update labels Jun 3, 2026
Attempt 1/3 - fixes based on AI review
@github-actions
Copy link
Copy Markdown
Contributor Author

github-actions Bot commented Jun 3, 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 Jun 3, 2026

AI Review - Attempt 2/3

Image Description

Light render (plot-light.png): Warm off-white background (#FAF8F1). The plot shows a piano roll spanning 8 measures (m1–m9 on x-axis) with MIDI pitches B2–G5 on the y-axis labeled with note names (C3, D3, … G5). Alternating row shading distinguishes white keys (light beige #EBE7DC) from black keys (slightly darker #D3CDB8). MIDI note rectangles are colored on an Imprint sequential scale — green (#009E73) for low-velocity notes graduating through teal to blue (#4467A3) for high-velocity. A subtle translucent blue overlay highlights the climax region (m6), and a small bold-italic "ff" annotation marks the dynamic peak. Colorbar legend on right with musical dynamics labels (pp, p, mf, f, ff). Vertical beat lines are faint; measure boundaries are darker. Title, axis labels, and tick labels are all in dark ink — clearly readable against the light surface.
Legibility verdict: PASS — all text readable, no light-on-light issues.

Dark render (plot-dark.png): Background is warm near-black (#1A1A17). Title and all chrome text renders in light ink (#F0EFE8 / #B8B7B0) — fully readable against the dark surface. Piano keyboard row alternation is visible but subtle (very dark charcoal vs near-black). MIDI note colors are identical to the light render — the green-to-blue Imprint sequential gradient is unchanged; only the surrounding chrome (background, text, legend frame, row shading) has flipped. The "ff" annotation is legible. No dark-on-dark failures detected.
Legibility verdict: PASS — all text readable in both themes.

Score: 89/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 7 10
Total 89 100

Visual Quality (28/30)

  • VQ-01: Text Legibility (7/8) — title 12pt, axis labels 10pt, tick labels 8pt; all follow style-guide defaults and are readable in both renders. Minor deduction: the "ff" annotation (size=2.5, ~7pt) is small for a 3200×1800 canvas.
  • VQ-02: No Overlap (6/6) — no collisions between text, annotations, or data rectangles.
  • VQ-03: Element Visibility (5/6) — note rectangles clearly visible; beat subdivision lines are intentionally very faint (alpha=0.35) and may be imperceptible on some displays. Minor deduction.
  • VQ-04: Color Accessibility (2/2) — Imprint sequential (green→blue) is CVD-safe; no red-green confusion.
  • VQ-05: Layout & Canvas (4/4) — 3200×1800 canvas (gate passed), generous margins, legend well-positioned.
  • VQ-06: Axis Labels & Title (2/2) — "Pitch" (with note names) and "Measure" with m1–m9 labels; spec-format title.
  • VQ-07: Palette Compliance (2/2) — imprint_seq (green #009E73 → blue #4467A3) for continuous velocity; backgrounds #FAF8F1 / #1A1A17; data colors identical between themes.

Design Excellence (14/20)

  • DE-01: Aesthetic Sophistication (6/8) — Domain-specific piano keyboard row shading (white vs. black key distinction), velocity colormap labeled with musical dynamics (pp→ff), climax highlight overlay, and narrative "ff" annotation all demonstrate clear design intent. Not a generic defaults chart.
  • DE-02: Visual Refinement (4/6) — Default grid replaced with custom beat/measure lines of different weights. Panel border kept (correct for enclosed grid). Elevated legend background. Row alternation adds refinement, though contrast between white-key and black-key rows is subtle.
  • DE-03: Data Storytelling (4/6) — Dynamic arc from quiet (green) to loud (blue) back to quiet is visually narrated. Climax highlight and annotation create a clear focal point at measure 6. Good editorial intent.

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) — Correct piano roll: horizontal rectangles at pitch × time.
  • SC-02: Required Features (4/4) — Note names on Y-axis ✓; black/white key row alternation ✓; beat+measure grid lines of different weights ✓; sequential velocity colormap ✓.
  • SC-03: Data Mapping (3/3) — X=start/end time, Y=MIDI pitch, fill=velocity; all axes correct.
  • SC-04: Title & Legend (3/3) — Title: piano-roll-midi · r · ggplot2 · anyplot.ai ✓; velocity colorbar with pp/p/mf/f/ff labels ✓.

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) — Covers onset, duration, pitch, and velocity; right-hand melody + left-hand bass; full dynamic arc.
  • DQ-02: Realistic Context (5/5) — Musically authentic C-major piano piece; C-F-Am-G progression; mf→ff climax→p resolution; realistic MIDI velocity values.
  • DQ-03: Appropriate Scale (4/4) — 96 notes (within 20–200 spec range); pitch range C3–G5 (appropriate piano register); velocity 30–127.

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3) — Flat script, no functions or classes.
  • CQ-02: Reproducibility (2/2) — set.seed(42) present.
  • CQ-03: Clean Imports (2/2) — Only ggplot2 and ragg imported, both used.
  • CQ-04: Code Elegance (2/2) — Clean layered grammar; no fake interactivity.
  • CQ-05: Output & API (1/1) — Saves as plot-{THEME}.png via ragg::agg_png at correct canvas size.

Library Mastery (7/10)

  • LM-01: Idiomatic Usage (4/5) — Multiple geom layers (geom_rect×3, geom_vline×2, annotate), scale_fill_gradient, guide_colorbar, expansion() — idiomatic ggplot2 grammar throughout.
  • LM-02: Distinctive Features (3/5) — Good use of layered composition but no especially distinctive ggplot2 features (e.g., coord_fixed, secondary axes, stat transforms, or faceting) beyond standard geoms.

Score Caps Applied

  • None — no cap conditions triggered.

Strengths

  • Perfect spec compliance: all four required features (note names, black/white key rows, beat+measure grid differentiation, velocity colormap) are implemented correctly
  • Musically authentic data with realistic C-major progression, proper MIDI note numbers, and a convincing dynamic arc (mf→ff climax→p resolution)
  • Effective storytelling: climax highlight overlay + "ff" annotation create a clear, readable narrative focal point
  • Correct Imprint sequential palette (green→blue) for continuous velocity data; full theme-adaptive chrome with no dark-on-dark or light-on-light failures

Weaknesses

  • Piano keyboard row contrast is low in both themes (light: #EBE7DC vs #D3CDB8; dark: #222220 vs #1D1D1B) — the spec asks for "white and dark" alternation, but the two row types look nearly identical; increasing contrast (e.g., light theme KEY_BLACK → #C8C2AE) would better communicate the piano layout
  • "ff" annotation at size=2.5 (~7pt on 3200×1800 canvas) is small and could be bumped to size=3.5–4 for better visibility at catalog scale

Issues Found

  1. VQ-03 MINOR: Beat subdivision lines (alpha=0.35, linewidth=0.12) may be imperceptible on some displays — consider raising alpha to 0.5 or linewidth to 0.18 to ensure they're visible without competing with measure boundaries.
  2. DE-02 MINOR: Piano keyboard row shading contrast is subtle — white-key and black-key rows look nearly the same in both themes. Increase contrast between the two row types for clearer piano keyboard reading.

AI Feedback for Next Attempt

Strong implementation overall — spec compliance and data quality are excellent. If a repair is triggered: (1) increase piano keyboard row contrast by darkening KEY_BLACK by ~10–15% in both themes; (2) raise the "ff" annotation size from 2.5 to 3.5; (3) raise beat subdivision line alpha from 0.35 to 0.5. These are minor polish items — the core piano roll logic is correct.

Verdict: APPROVED

@github-actions github-actions Bot added quality:89 Quality score 89/100 ai-approved Quality OK, ready for merge and removed quality:86 Quality score 86/100 labels Jun 3, 2026
@MarkusNeusinger MarkusNeusinger merged commit f768496 into main Jun 3, 2026
3 checks passed
@MarkusNeusinger MarkusNeusinger deleted the implementation/piano-roll-midi/ggplot2 branch June 3, 2026 04:02
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:89 Quality score 89/100

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant