Skip to content

feat(altair): implement piano-roll-midi#8306

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

feat(altair): implement piano-roll-midi#8306
MarkusNeusinger merged 4 commits into
mainfrom
implementation/piano-roll-midi/altair

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

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

Implementation: piano-roll-midi - python/altair

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

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

Parent Issue: #4565


🤖 impl-generate workflow

github-actions Bot and others added 2 commits June 3, 2026 03:40
Regen from quality 90. Addressed:
- Fixed canvas: width=620, height=330, scale_factor=4.0 with PIL padding to exact 3200×1800
- Fixed title to piano-roll-midi · python · altair · anyplot.ai (added language token, fixed anyplot.ai)
- Fixed output files to plot-{THEME}.png + plot-{THEME}.html
- Added full ANYPLOT_THEME support with theme-adaptive chrome (PAGE_BG, INK, INK_SOFT, ELEVATED_BG)
- Replaced custom velocity palette with Imprint sequential (#009E73→#4467A3) — fixes perceptual uniformity weakness
- Made piano key background rows theme-adaptive (light/dark alternating shading)
- Added sys.path fix to prevent altair.py shadowing installed altair package
- Added configure_view/configure_axis/configure_legend with full theme tokens

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Jun 3, 2026

AI Review - Attempt 1/3

Image Description

Light render (plot-light.png): Rendered on a warm off-white #FAF8F1 background (correct). The piano roll shows note bars spanning 8 measures (M1–M9) across the X-axis and ~40 pitch rows (G#2 through G#5) on the Y-axis. Note bars use the Imprint sequential colormap — green (#009E73) for low velocity (~40, soft) transitioning to blue (#4467A3) for high velocity (~127, loud). Alternating row shading (white-key rows #F0EDE6, black-key rows #D8D4CC) provides a subtle but visible piano keyboard layout. Dashed beat grid lines at opacity 0.25 and solid measure boundary lines at opacity 0.5 create clear temporal structure. The title "piano-roll-midi · python · altair · anyplot.ai" is bold, dark, centered, and occupies ~60% of the plot width. Y-axis label "Pitch" and X-axis label "Measure" are clearly readable. Velocity colorbar on the right with labels "127"/"40" is legible. Layer labels "Melody", "Chords", "Bass" appear in italic at the right margin. All text is readable against the light background — no light-on-light issues.

Dark render (plot-dark.png): Rendered on warm near-black #1A1A17 (correct). The title and all axis labels switch to light text (#F0EFE8 / #B8B7B0) and are clearly readable against the dark surface. Note bar data colors are identical to the light render — the same green-to-blue gradient confirming only chrome flips between themes. Alternating row shading (white-key rows #242420 vs black-key rows #1A1A17) is very subtle in dark mode but distinguishable on inspection. The velocity colorbar legend text and layer labels are readable. No dark-on-dark text failure detected anywhere in the render.

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

Score: 91/100

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

Visual Quality (29/30)

  • VQ-01: Text Legibility (7/8) — Title, axis labels, and measure ticks all clearly readable in both themes. Y-axis note-name labels at fontSize=9 are on the small side for 40 rows but readable at full resolution; slight mobile concern.
  • VQ-02: No Overlap (6/6) — No text or element overlap detected; layer labels and legend are well separated.
  • VQ-03: Element Visibility (6/6) — All note bars clearly visible in both themes; alternating rows and grid lines rendered at appropriate opacity.
  • VQ-04: Color Accessibility (2/2) — Imprint sequential colormap (green → blue) is CVD-safe; no red-green-only encoding.
  • VQ-05: Layout & Canvas (4/4) — Canvas correctly padded to 3200×1800; canvas gate passed; clean proportions with title at ~60% width.
  • VQ-06: Axis Labels & Title (2/2) — X-axis "Measure" with M1–M9 labels, Y-axis "Pitch" with note names. Correct title format.
  • VQ-07: Palette Compliance (2/2) — Imprint sequential (#009E73#4467A3) for continuous velocity data; plot backgrounds #FAF8F1 light / #1A1A17 dark; both renders theme-correct.

Design Excellence (14/20)

  • DE-01: Aesthetic Sophistication (6/8) — Piano keyboard alternating background, five-layer composition, velocity gradient, and musical layer labels at the right margin produce a professional DAW-like aesthetic well above generic defaults.
  • DE-02: Visual Refinement (4/6) — strokeWidth=0 removes view border; configure_axis(grid=False) replaced by deliberate custom beat/measure rule layers; cornerRadius=3 on note bars adds polish; dashed vs solid grid differentiates beat/measure hierarchy clearly.
  • DE-03: Data Storytelling (4/6) — Layer labels ("Bass", "Chords", "Melody") guide the viewer through musical structure; velocity gradient communicates dynamics visually; interactive legend selection enables exploratory filtering.

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) — Piano roll with horizontal note bars correctly implements the MIDI visualization.
  • SC-02: Required Features (4/4) — Note names on Y-axis ✓, alternating piano key row shading ✓, dashed beat grid + solid measure boundary lines ✓, sequential velocity colorscale ✓, auto-fit pitch range ±1 semitone margin ✓.
  • SC-03: Data Mapping (3/3) — Time (beats) on X-axis, pitch on Y-axis, velocity on color, note duration as bar width — all correct.
  • SC-04: Title & Legend (3/3) — Title matches required format; velocity gradient colorbar present; layer labels supplement legend.

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) — Shows bass line, chord voicings, and melodic phrases with varying rhythms and dynamics across 8 full measures; covers pitch, time, duration, and velocity.
  • DQ-02: Realistic Context (5/5) — C major harmonic progression with realistic chord voicings, bass line, and melodic phrases. Musically plausible and neutral.
  • DQ-03: Appropriate Scale (4/4) — 8 measures (32 beats), MIDI notes 45–79 (A2–G5), velocity 50–120. Appropriate demo scope.

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3) — No functions or classes; clean procedural top-down structure with labeled sections.
  • CQ-02: Reproducibility (2/2) — np.random.seed(42) set before any random calls.
  • CQ-03: Clean Imports (2/2) — All imports (altair, numpy, pandas, PIL, os, sys) are used.
  • CQ-04: Code Elegance (2/2) — Clean layer composition; no fake UI; sensible variable naming.
  • CQ-05: Output & API (1/1) — Saves plot-{THEME}.png and plot-{THEME}.html with correct naming.

Library Mastery (8/10)

  • LM-01: Idiomatic Usage (4/5) — Proper use of Altair layer composition (+), encoding types (Q/N), alt.condition for opacity, sort=pitch_labels for nominal axis ordering, configure_* chaining — all idiomatic.
  • LM-02: Distinctive Features (4/5) — Uses Altair-specific interactive features: selection_point(bind='legend') for layer filtering, selection_interval for brush in HTML output, alt.condition for conditional opacity. These are distinctly Altair capabilities.

Score Caps Applied

  • None

Strengths

  • All five spec requirements implemented: note names, alternating piano key rows, dashed beat + solid measure grid, Imprint sequential velocity colorscale, auto-fit pitch range.
  • Five-layer Altair composition (background rows + beat grid + measure grid + note bars + layer labels) is idiomatic and sophisticated.
  • Musical layer labels ("Bass", "Chords", "Melody") at the right margin add excellent data storytelling.
  • Interactive legend selection and HTML brush export leverage Altair's distinctive strengths.
  • Theme-adaptive chrome correctly propagated — both renders fully readable.
  • Canvas correctly padded to 3200×1800 with PIL; fail-loud guard on overshoot is production-quality.

Weaknesses

  • Y-axis tick labels at fontSize=9 are on the small side for 40 rows; raising to fontSize=10 (matching the X-axis) would improve mobile readability without crowding.
  • Black-key vs white-key row contrast in dark mode (#1A1A17 vs #242420) is very subtle — the piano keyboard metaphor could be strengthened by using a slightly higher-contrast value (e.g., #2D2D29) for white-key rows in dark mode.
  • Velocity colormap direction (green=soft, blue=loud) is technically correct (Imprint sequential) but counterintuitive relative to common DAW conventions (warm=loud, cool=soft); a code comment explaining the Imprint constraint would aid future maintainers.

Issues Found

  1. VQ-01 MINOR: Y-axis labelFontSize=9 is the only sizing point below the recommended minimum for this density
    • Fix: Change axis=alt.Axis(labelFontSize=9, ...) on the Y-axis to labelFontSize=10

AI Feedback for Next Attempt

Implementation is high quality and spec-complete. The only meaningful improvements are: (1) raise Y-axis tick label fontsize from 9 to 10 for mobile readability; (2) slightly strengthen the black/white key row contrast in dark mode. The five-layer Altair composition pattern with interactive legend selection is the right architectural choice — keep it.

Verdict: APPROVED

@github-actions github-actions Bot added quality:91 Quality score 91/100 ai-approved Quality OK, ready for merge labels Jun 3, 2026
@MarkusNeusinger MarkusNeusinger merged commit 8b4a18f into main Jun 3, 2026
@MarkusNeusinger MarkusNeusinger deleted the implementation/piano-roll-midi/altair branch June 3, 2026 03:48
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 quality:91 Quality score 91/100

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant