Skip to content

feat(bokeh): implement piano-roll-midi#8304

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

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

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

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

Implementation: piano-roll-midi - python/bokeh

Implements the python/bokeh version of piano-roll-midi.

File: plots/piano-roll-midi/implementations/python/bokeh.py

Parent Issue: #4565


🤖 impl-generate workflow

github-actions Bot added 2 commits June 3, 2026 03:34
Regen from quality 90. Addressed:
- Fixed canvas to 3200×1800 (was 4800×2700)
- Added ANYPLOT_THEME support (light/dark) with full theme-adaptive chrome
- Replaced forbidden export_png + Turbo256 with Selenium screenshot + Imprint sequential palette
- Fixed title format: piano-roll-midi · python · bokeh · anyplot.ai
- Fixed output filenames: plot-{THEME}.png and plot-{THEME}.html
- Added sys.path fix to prevent bokeh.py from shadowing the package
- Added toolbar_location=None, correct min_border_* values, PIL crop for exact 3200×1800
- Velocity palette: blue (#4467A3) → red (#AE3030) sequential for note visibility in both themes
@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Jun 3, 2026

AI Review - Attempt 1/3

Image Description

Light render (plot-light.png): Warm off-white (#FAF8F1) background. Piano keyboard rows alternate between near-white (#FFFDF6, white keys) and soft gray (#E5E1D8, black keys), clearly distinguishable. Note rectangles span a blue (#4467A3) to red (#AE3030) velocity gradient — low-velocity notes at beats 0–2 (C4, D4) appear blue; the I-IV-V-I chord climax at beats 10–12 appears vivid red. Y-axis shows note names B3–D#5 via label overrides; X-axis shows beat numbers 0–16. Title, axis labels, and colorbar ('Velocity') are all in dark ink and clearly readable. Custom vertical grid lines mark beats (thin, subtle) and measure boundaries (stronger). All text is readable against the light background.

Dark render (plot-dark.png): Warm near-black (#1A1A17) background. Piano key rows alternate between dark charcoal (#262521, white keys) and near-black (#131310, black keys) — contrast is subtler than light but visible. Note rectangle colors are identical to the light render (same blue→red velocity gradient). Title and axis labels render in near-white (#F0EFE8); tick labels in #B8B7B0 — both adequately visible. Colorbar label and ticks in light colors. No dark-on-dark text failures. Both renders pass legibility.

Score: 89/100

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

Visual Quality (28/30)

  • VQ-01: Text Legibility (8/8) — All font sizes explicitly set (50pt title, 42pt axis labels, 34pt ticks, 34pt/28pt colorbar). Proportions balanced in both renders.
  • VQ-02: No Overlap (6/6) — 17 pitch rows with note names, 17 beat ticks, no collisions.
  • VQ-03: Element Visibility (6/6) — Note rectangles clearly visible; height 0.82 with gap. Velocity gradient fully distinguishable.
  • VQ-04: Color Accessibility (1/2) — Blue→red gradient is generally legible but mid-range muted-purple values may be harder to distinguish under some CVD conditions (not a mandated Imprint cmap optimized for CVD safety).
  • VQ-05: Layout & Canvas (4/4) — 3200×1800, toolbar_location=None, min_border correctly set. No clipping. Clean colorbar placement.
  • VQ-06: Axis Labels & Title (2/2) — 'Time (beats)' with units; 'Pitch' with note-name tick labels as context. Title format correct.
  • VQ-07: Palette Compliance (1/2) — Custom velocity colormap lerps between Imprint endpoints (#4467A3 → #AE3030) but is not the mandated imprint_seq (green→blue) or imprint_div (red↔neutral↔blue). Imprint palette colors used but mandated cmap not applied. Plot backgrounds (#FAF8F1 / #1A1A17) and chrome are correct.

Design Excellence (13/20)

  • DE-01: Aesthetic Sophistication (5/8) — Domain-specific choices (piano key shading, differentiated beat/measure grid, velocity gradient) clearly elevate above defaults. Typography uses size hierarchy but no weight variation. Between configured-default (4) and strong-design (6).
  • DE-02: Visual Refinement (4/6) — Custom grid lines replace Bokeh defaults, outline_line_color=None, all chrome tokens applied. Axis lines present but appropriate for piano-roll grid context.
  • DE-03: Data Storytelling (4/6) — Musical arc is visually readable: blue low-velocity scale runs → red fortissimo chord climax → resolution. Measure boundaries reinforce structure. No section annotations but color hierarchy guides the viewer.

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) — Correct piano roll: horizontal rect per note, pitch on y, time on x, width=duration.
  • SC-02: Required Features (4/4) — Note names on y-axis, alternating piano key rows, differentiated beat/measure grid lines, velocity color scale, pitch range auto-fit.
  • SC-03: Data Mapping (3/3) — start→x center, duration→width, pitch→y, velocity→color. All axes show all data.
  • SC-04: Title & Legend (3/3) — Title 'piano-roll-midi · python · bokeh · anyplot.ai' correct. Colorbar 'Velocity' with ticks 40/60/80/100/120.

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) — Scalar runs (eighth notes), block chords (quarters), sustains (half notes). Velocity 55–120 (soft→fortissimo). Both white-key and black-key pitches.
  • DQ-02: Realistic Context (5/5) — C major scale runs + I-IV-V-I chord progression + melodic resolution. Genuine DAW content, neutral.
  • DQ-03: Appropriate Scale (4/4) — MIDI note numbers correct (C4=60). Velocity within standard (0–127). Timing in beats. Note durations musically realistic.

Code Quality (9/10)

  • CQ-01: KISS Structure (2/3) — _lerp_hex function defined at module level is a minor KISS violation; otherwise follows imports→data→plot→save.
  • CQ-02: Reproducibility (2/2) — All data hardcoded; fully deterministic.
  • CQ-03: Clean Imports (2/2) — All imports used (io, os, sys, time, Path, numpy, bokeh, PIL, selenium).
  • CQ-04: Code Elegance (2/2) — Clean, Pythonic. No fake UI. HoverTool appropriate for Bokeh.
  • CQ-05: Output & API (1/1) — Saves plot-{THEME}.html and plot-{THEME}.png with current API.

Library Mastery (9/10)

  • LM-01: Idiomatic Usage (5/5) — ColumnDataSource for both bg and note layers, Range1d, FixedTicker+major_label_overrides, level='underlay', ColorBar+LinearColorMapper, HoverTool with template — all idiomatic Bokeh.
  • LM-02: Distinctive Features (4/5) — Multi-layer ColumnDataSource rendering (underlay background + note rects), HoverTool templates, declarative LinearColorMapper+ColorBar, major_label_overrides for domain labels, HTML artifact with toolbar.

Score Caps Applied

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

Strengths

  • Correct piano roll implementation with all spec features: note-name y-axis, piano key row shading, differentiated beat/measure grid, velocity colormap, auto-fit pitch range
  • Domain-specific design choices (alternating key rows, stronger measure lines) show musical context understanding
  • Theme-adaptive chrome fully wired through all elements (title, axis labels, ticks, colorbar, background)
  • Excellent data: realistic C major musical phrase covering scale runs, chord progressions, and melodic resolution with meaningful velocity variation

Weaknesses

  • Velocity colormap (blue #4467A3 → red #AE3030) uses Imprint palette endpoints but is not the mandated imprint_seq (green→blue) or imprint_div (red↔neutral↔blue) — switch to imprint_div (built from the Imprint endpoints with theme-adaptive neutral midpoint) or imprint_seq; if semantics require blue=soft/red=loud, the reversed imprint_div direction is the closest compliant option
  • DE-01 could improve: add subtle font-weight variation (e.g., bold title, regular axis labels) or note-name annotations at measure boundaries to lift visual hierarchy
  • _lerp_hex function at module level is a minor KISS violation — inline the interpolation directly into the palette list comprehension

Issues Found

  1. VQ-07 / PARTIAL: Custom velocity colormap deviates from style-guide mandate
    • Fix: Replace _lerp_hex("#4467A3", "#AE3030", t/255.0) with imprint_div reversed (blue→neutral→red) or imprint_seq (green→blue) for single-polarity velocity
  2. DE-01 LOW: Typography lacks weight hierarchy
    • Fix: Set p.title.text_font_style = "bold" for the title; consider adding a small musical-section annotation at beat 8 or 13 to surface the structure
  3. CQ-01 MINOR: _lerp_hex helper function
    • Fix: Inline as a lambda or single expression inside the palette comprehension

AI Feedback for Next Attempt

Replace the custom velocity colormap with the mandated Imprint cmap: for blue=low-velocity/red=high-velocity semantics, build an imprint_div-style palette reversed — [_lerp_hex("#4467A3", midpoint, t/127.0) for t in range(128)] + [_lerp_hex(midpoint, "#AE3030", t/127.0) for t in range(128)] where midpoint is "#FAF8F1" (light) / "#1A1A17" (dark). If the neutral midpoint washes out mid-velocity notes, use imprint_seq (green→blue) instead. Inline the _lerp_hex function into the comprehension. Add p.title.text_font_style = "bold" for stronger hierarchy. These three changes should push the score above 90.

Verdict: REJECTED

@github-actions github-actions Bot added quality:89 Quality score 89/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): The plot renders on a warm off-white (#FAF8F1) background. The piano roll shows horizontal note rectangles spanning beats 0–16 on the x-axis and pitches B3–D#5 on the y-axis (labeled with note names via major_label_overrides). Alternating row shading distinguishes white piano keys (slightly lighter cream rows) from black keys (slightly darker grey-cream rows). Notes are colored via imprint_seq (green #009E73 for low-velocity/soft notes, blue #4467A3 for high-velocity/loud notes). Custom beat grid lines at every quarter note with stronger lines (40% opacity, 2.5px) at measure boundaries (beats 0, 4, 8, 12, 16) and lighter lines (12% opacity, 1px) at intermediate beats. A color bar on the right labeled "Velocity" with ticks at 40, 60, 80, 100, 120 is clearly visible. Title "piano-roll-midi · python · bokeh · anyplot.ai" in dark ink, all axis labels and tick labels in INK/INK_SOFT tokens, fully readable against the light background.

Dark render (plot-dark.png): The same plot renders on a warm near-black (#1A1A17) background. Title, axis labels, and tick labels are all rendered in light text (#F0EFE8 / #B8B7B0) — clearly readable, with no dark-on-dark failures detected anywhere. The alternating row shading is subtly visible as slightly lighter dark rows (white keys: #262521) vs. near-black rows (black keys: #131310). All note rectangle data colors are identical to the light render — the imprint_seq velocity gradient is invariant across themes, confirming correct chrome-only theme switching. The color bar labels and velocity title are legible on the dark surface.

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

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

Visual Quality (30/30)

  • VQ-01: Text Legibility (8/8) — All font sizes explicitly set (50pt title, 42pt axis labels, 34pt tick labels). Readable in both themes.
  • VQ-02: No Overlap (6/6) — No text or element overlaps. Chord notes on separate pitch rows.
  • VQ-03: Element Visibility (6/6) — Note rectangles clearly visible; velocity gradient legible; color bar readable.
  • VQ-04: Color Accessibility (2/2) — imprint_seq (green→blue) is CVD-safe. No red-green sole encoding.
  • VQ-05: Layout & Canvas (4/4) — 3200×1800, canvas gate passed, min_border values correctly reserve space. Color bar well-placed.
  • VQ-06: Axis Labels & Title (2/2) — X: "Time (beats)", Y: "Pitch", title correct format.
  • VQ-07: Palette Compliance (2/2) — VELOCITY_PALETTE correctly interpolates #009E73→#4467A3 (imprint_seq). Backgrounds #FAF8F1 / #1A1A17. Data colors identical in both renders.

Design Excellence (12/20)

  • DE-01: Aesthetic Sophistication (5/8) — Professional piano roll with domain-appropriate alternating key shading and custom grid differentiating beats from measures. Intentional velocity-color hierarchy. Solid execution but not visually inventive beyond spec conventions.
  • DE-02: Visual Refinement (4/6) — Custom manual grid lines replace bokeh default grid. outline_line_color=None removes frame. Alternating rows subtle and non-competing. Could further refine by removing tick marks for a cleaner look.
  • DE-03: Data Storytelling (3/6) — Musical narrative arc (crescendo→climax→resolution) is encoded in velocity colors, but no annotations or focal emphasis guide the viewer to notice the story. Storytelling is implicit rather than intentional.

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) — Correct piano roll: horizontal rects by pitch (y) and time (x), width=duration, color=velocity.
  • SC-02: Required Features (4/4) — Note names on y-axis (major_label_overrides), alternating key-row shading, differentiated beat/measure grid, sequential velocity colormap.
  • SC-03: Data Mapping (3/3) — X=time in beats, Y=pitch as note names, color=velocity, width=duration. Auto-fit pitch range with 1-note margin.
  • SC-04: Title & Legend (3/3) — Title: "piano-roll-midi · python · bokeh · anyplot.ai" correct. ColorBar labeled "Velocity" with correct tick marks.

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) — Covers scalar melody (scales), polyphony (block chords), varying durations (eighth→whole notes), full velocity range (55–127), 8 measures.
  • DQ-02: Realistic Context (5/5) — C major phrase with I-IV-V-I progression. Velocities in realistic MIDI range. Neutral, non-controversial content.
  • DQ-03: Appropriate Scale (4/4) — Pitch range B3–D#5 auto-fits data with 1-note margin. Time 0–16 beats. Colormap low=40 high=127 spans practical MIDI range.

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3) — No functions or classes. Flat, readable script.
  • CQ-02: Reproducibility (2/2) — Fully deterministic; all notes hardcoded, no random state.
  • CQ-03: Clean Imports (2/2) — All imports used; no unused imports.
  • CQ-04: Code Elegance (2/2) — No fake UI. Appropriate complexity. Inline VELOCITY_PALETTE computation clean.
  • CQ-05: Output & API (1/1) — Saves plot-{THEME}.png and plot-{THEME}.html. Correct API.

Library Mastery (9/10)

  • LM-01: Idiomatic Usage (5/5) — ColumnDataSource, LinearColorMapper, ColorBar, HoverTool, FixedTicker, major_label_overrides, level='underlay', toolbar_location=None. Fully idiomatic bokeh.
  • LM-02: Distinctive Features (4/5) — Strong use: level='underlay' for background rects, major_label_overrides for note name axis, LinearColorMapper+ColorBar for velocity, HoverTool with format strings, interactive HTML. No advanced transforms or server callbacks.

Score Caps Applied

  • None

Strengths

  • Correct imprint_seq colormap (green→blue) for velocity mapping — exact #009E73→#4467A3 interpolation verified
  • All spec requirements met: note names on y-axis, alternating piano key shading, differentiated beat/measure grid lines, velocity color bar
  • Excellent bokeh feature utilization: ColorBar, HoverTool, FixedTicker, major_label_overrides, ColumnDataSource with level=underlay
  • Both themes correctly adapted with appropriate tokens throughout (no dark-on-dark, correct backgrounds)
  • Musical phrase is rich and domain-authentic (C major scales + I-IV-V-I chords + melodic resolution)

Weaknesses

  • DE-01 moderate: piano roll design is professional but relies on standard DAW conventions without standout visual innovation beyond the spec requirements
  • DE-02 partially met: custom grid lines are a nice touch, but removing more default chrome (e.g. axis tick marks) would improve refinement
  • DE-03 limited: musical narrative arc is present in the data but the visualization provides no annotations or focal emphasis to guide the viewer to notice the crescendo→climax→resolution story

Issues Found

  1. DE-03 LOW: Musical narrative is entirely implicit — the velocity arc tells a dynamic story but nothing in the design guides the viewer to it
    • Fix: Add a subtle annotation or reference line at the climax beat (beat 10-11) to make the narrative intentional; or vary alpha/line_width slightly with velocity to reinforce the dynamic arc visually

AI Feedback for Next Attempt

The core implementation is strong — spec compliance and visual quality are perfect. To push Design Excellence higher: (1) add a single annotation at the dynamic climax (beat 10-11, "fortissimo") to make the musical narrative explicit; (2) remove y-axis major tick marks (keep labels) for a cleaner look; (3) consider slightly varying note rectangle border width with velocity for an additional redundant encoding of dynamics. These are refinements, not fixes — the current render is APPROVED.

Verdict: APPROVED

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant