Skip to content

feat(pygal): implement heatmap-chromagram#4960

Merged
github-actions[bot] merged 8 commits intomainfrom
implementation/heatmap-chromagram/pygal
Mar 23, 2026
Merged

feat(pygal): implement heatmap-chromagram#4960
github-actions[bot] merged 8 commits intomainfrom
implementation/heatmap-chromagram/pygal

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

Implementation: heatmap-chromagram - pygal

Implements the pygal version of heatmap-chromagram.

File: plots/heatmap-chromagram/implementations/pygal.py

Parent Issue: #4564


🤖 impl-generate workflow

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Mar 17, 2026

AI Review - Attempt 1/3

Image Description

The plot displays a chromagram heatmap with 12 pitch classes (B at top, C at bottom) on the y-axis labeled "Pitch Class" and time from 0.0 to 7.2+ seconds on the x-axis labeled "Time (seconds)". An inferno-inspired sequential colormap ranges from near-black/dark purple (0.0 energy) through magenta and orange to bright yellow (1.0 energy). A vertical colorbar on the right is titled "Energy" with scale marks at 0.0, 0.5, and 1.0. The title reads "heatmap-chromagram · pygal · pyplots.ai". Four chord regions are clearly visible: C major (C, E, G bright from 0–1.6s), G major (G, B, D bright from 2–4s), A minor (A, C, E bright from 4–5.6s), and F major (F, A, C bright from 6–7.9s). Background noise is visible as low-intensity dark cells throughout.

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

Visual Quality (28/30)

  • VQ-01: Text Legibility (7/8) — All font sizes explicitly set (title 64px, axis titles 48px, pitch labels 44px, time labels 36px). All text clearly readable.
  • VQ-02: No Overlap (6/6) — No overlapping text. Time labels show every 10th frame to prevent crowding.
  • VQ-03: Element Visibility (6/6) — Heatmap cells are well-sized and clearly visible with good density.
  • VQ-04: Color Accessibility (4/4) — Inferno-inspired colormap is perceptually uniform and colorblind-safe.
  • VQ-05: Layout & Canvas (3/4) — Good overall layout; some wasted space at left/right margins.
  • VQ-06: Axis Labels & Title (2/2) — "Pitch Class" and "Time (seconds)" with units.

Design Excellence (12/20)

  • DE-01: Aesthetic Sophistication (5/8) — Custom inferno-inspired colormap with smooth interpolation, clean white background, styled bold axis titles. Above defaults but not publication-level polish.
  • DE-02: Visual Refinement (4/6) — No grid lines (appropriate for heatmap), clean colorbar with border, good whitespace. Some margin refinement possible.
  • DE-03: Data Storytelling (3/6) — Chord progression is visible through color patterns but there's no explicit visual hierarchy or emphasis guiding the viewer to the harmonic transitions.

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) — Correct heatmap type showing chromagram data.
  • SC-02: Required Features (4/4) — All 12 pitch classes, sequential colormap, colorbar, time axis in seconds, realistic harmonic patterns.
  • SC-03: Data Mapping (3/3) — X=time, Y=pitch class, color=energy all correctly mapped.
  • SC-04: Title & Legend (3/3) — Title format "heatmap-chromagram · pygal · pyplots.ai" correct. Colorbar serves as legend.

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) — Shows all aspects: varying energy levels, clear chord transitions, background noise, four distinct chords (C, G, Am, F).
  • DQ-02: Realistic Context (5/5) — Realistic MIR scenario with C→G→Am→F chord progression and smooth transitions between chords.
  • DQ-03: Appropriate Scale (4/4) — Normalized energy 0–1, 0.1s frame duration, 80 frames covering 8 seconds.

Code Quality (9/10)

  • CQ-01: KISS Structure (2/3) — Custom class extending Graph is necessary for pygal heatmaps but adds structural complexity.
  • CQ-02: Reproducibility (2/2) — np.random.seed(42) set.
  • CQ-03: Clean Imports (2/2) — All imports used. sys.path manipulation required to avoid pygal name collision.
  • CQ-04: Code Elegance (2/2) — Well-structured code. SVG tooltips via <title> elements are native pygal functionality.
  • CQ-05: Output & API (1/1) — Saves as plot.png via render_to_png.

Library Mastery (6/10)

  • LM-01: Idiomatic Usage (3/5) — Correctly extends Graph base class with _plot/_compute methods, uses svg.node API and Style system. However, most rendering is custom SVG work rather than pygal high-level API.
  • LM-02: Distinctive Features (3/5) — Uses pygal's Graph extension model, SVG node system, native tooltips via <title> elements, and render_to_png/render_to_file. These are distinctive to pygal.

Score Caps Applied

  • None

Strengths

  • Excellent data quality with realistic C→G→Am→F chord progression and smooth transitions
  • Full spec compliance — all required features present (12 pitch classes, sequential colormap, colorbar, time axis)
  • Custom inferno-inspired colormap with smooth color interpolation between 10 anchor points
  • Native SVG tooltips showing pitch, time, and energy values for each cell
  • Clean colorbar implementation with proper scale markings and "Energy" title

Weaknesses

  • No visual hierarchy or emphasis to guide the viewer through the chord progression (DE-03)
  • Layout has some wasted margin space, especially on left and right sides (VQ-05)
  • Mostly custom SVG rendering rather than leveraging pygal's higher-level patterns (LM-01)

Issues Found

  1. DE-03 LOW: No visual hierarchy — the four chord sections blend together without visual emphasis
    • Fix: Add subtle vertical separator lines or section labels at chord boundaries to highlight the C→G→Am→F progression
  2. DE-01 MODERATE: Styling is good but not publication-level
    • Fix: Consider adding a subtle background tint to the heatmap area, or thin horizontal lines between pitch classes for visual grouping
  3. LM-01 MODERATE: Heavy reliance on manual SVG work
    • Fix: Explore using more of pygal's built-in configuration and rendering pipeline where possible

AI Feedback for Next Attempt

Improve data storytelling (DE-03): add visual markers or subtle separators at chord transition boundaries (frames 20, 40, 60) to emphasize the harmonic progression. Consider thin white or semi-transparent vertical lines at transitions. Improve layout by tightening margins to maximize canvas utilization. For design polish (DE-01), consider subtle horizontal separator lines between pitch class rows to aid readability.

Verdict: REJECTED

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

🔧 Repair Attempt 1/3

Applied fixes based on AI review feedback.

Status: Repair completed, re-triggering review...


🤖 impl-repair

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Mar 17, 2026

AI Review - Attempt 2/3

Image Description

The plot displays a chromagram heatmap with 12 pitch classes (B at top, C at bottom) on the y-axis labeled "Pitch Class" and time from 0.0 to 7.2+ seconds on the x-axis labeled "Time (seconds)". The title reads "heatmap-chromagram · pygal · pyplots.ai" at the top. An inferno-inspired sequential colormap is used, ranging from near-black/dark purple (0.0 energy) through magenta and orange to bright yellow (1.0 energy). A vertical colorbar on the right is titled "Energy" with tick marks at 0.0, 0.5, and 1.0. Four chord region labels appear in italic bold gray text above the heatmap: "C major", "G major", "A minor", and "F major", with dashed vertical separator lines at chord boundaries. Subtle alternating background bands behind the heatmap distinguish regions. The chord progression is clearly visible: C/E/G rows are bright during 0–1.6s (C major), G/B/D bright during 2–4s (G major), A/C/E bright during 4–5.6s (A minor), and F/A/C bright during 6–7.9s (F major). Low-energy background noise appears as dark purple throughout non-active pitch rows.

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

Visual Quality (28/30)

  • VQ-01: Text Legibility (7/8) — All font sizes explicitly set (title 64px, axis titles 48px, pitch labels ~44px, time labels 36px, chord labels 38px, colorbar labels 36px). All clearly readable. Slight deduction: pitch row labels could be a touch larger for perfect readability at full resolution.
  • VQ-02: No Overlap (6/6) — No overlapping text anywhere. Time labels use every-10th-frame stepping to prevent crowding.
  • VQ-03: Element Visibility (6/6) — Heatmap cells are well-sized, color differences clearly distinguishable across the full energy range.
  • VQ-04: Color Accessibility (4/4) — Inferno-inspired colormap is perceptually uniform and colorblind-safe (sequential purple→orange→yellow).
  • VQ-05: Layout & Canvas (3/4) — Good overall layout with heatmap filling most of the canvas. Left margin is slightly generous due to rotated y-axis title positioning (240px offset). Minor wasted space.
  • VQ-06: Axis Labels & Title (2/2) — "Pitch Class" and "Time (seconds)" are descriptive with units.

Design Excellence (13/20)

  • DE-01: Aesthetic Sophistication (5/8) — Custom inferno colormap with smooth 10-point interpolation, clean white background, bold styled axis titles, italic chord region labels. Clearly above library defaults but not publication-level polish (e.g., no refined typography hierarchy, no subtle background texture).
  • DE-02: Visual Refinement (4/6) — No grid lines (appropriate for heatmap), clean heatmap border, dashed vertical separators at chord boundaries, subtle alternating background bands, colorbar with border. Good refinement but could benefit from thin horizontal separators between pitch rows for visual grouping.
  • DE-03: Data Storytelling (4/6) — Chord region labels ("C major", "G major", etc.) and dashed separators effectively guide the viewer through the harmonic progression. Alternating background bands reinforce section boundaries. The viewer can immediately identify the chord structure. Could be elevated further with stronger emphasis on transitions or a summary annotation.

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) — Correct heatmap type showing chromagram data.
  • SC-02: Required Features (4/4) — All 12 pitch classes labeled C to B, sequential colormap (inferno-inspired), colorbar with energy scale, time axis in seconds, realistic harmonic patterns with chord alternation.
  • SC-03: Data Mapping (3/3) — X=time frames, Y=pitch classes, color=energy intensity — all correctly mapped.
  • SC-04: Title & Legend (3/3) — Title format "heatmap-chromagram · pygal · pyplots.ai" correct. Colorbar serves as energy legend.

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) — Shows all aspects: varying energy levels per pitch class, clear chord transitions with smoothing, background noise, four distinct chords (C major, G major, A minor, F major).
  • DQ-02: Realistic Context (5/5) — Realistic MIR scenario with I–V–vi–IV chord progression (one of the most common in popular music), smooth transitions between chords, and plausible energy distribution.
  • DQ-03: Appropriate Scale (4/4) — Normalized energy 0–1, 0.1s frame duration, 80 frames covering 8 seconds — all appropriate for chroma feature extraction.

Code Quality (9/10)

  • CQ-01: KISS Structure (2/3) — Custom class extending pygal's Graph is necessary since pygal has no native heatmap, but adds structural complexity beyond the ideal flat script pattern.
  • CQ-02: Reproducibility (2/2) — np.random.seed(42) set.
  • CQ-03: Clean Imports (2/2) — All imports used. sys.path manipulation is necessary to avoid pygal name collision.
  • CQ-04: Code Elegance (2/2) — Well-structured custom Graph subclass. SVG tooltips via native <title> elements are legitimate pygal functionality, not fake interactivity.
  • CQ-05: Output & API (1/1) — Saves as plot.png via render_to_png, also generates plot.svg and plot.html.

Library Mastery (6/10)

  • LM-01: Idiomatic Usage (3/5) — Correctly extends pygal's Graph base class with _plot() and _compute() methods, uses the svg.node() API for SVG construction, and leverages the Style configuration system. However, the majority of rendering is hand-built SVG rather than using pygal's higher-level chart abstractions.
  • LM-02: Distinctive Features (3/5) — Uses pygal's Graph extension model (subclassing Graph with custom _plot), SVG node construction API (svg.node()), native SVG tooltips via <title> elements, Style system, and render_to_png/render_to_file methods. These are distinctive to pygal's architecture.

Score Caps Applied

  • None

Strengths

  • Excellent data quality with realistic I–V–vi–IV chord progression and smooth inter-chord transitions
  • Full spec compliance with all required features present and correctly implemented
  • Effective data storytelling with chord region labels, dashed separators, and alternating background bands
  • Custom inferno-inspired colormap with smooth 10-point color interpolation
  • Native SVG tooltips showing pitch, time, and energy values for each cell (via <title> elements)
  • Clean colorbar implementation with proper scale markings and title

Weaknesses

  • Design polish not yet at publication level — lacks fine typographic hierarchy and subtle visual grouping (e.g., thin horizontal separators between pitch rows)
  • Left margin slightly oversized due to rotated y-axis title positioning
  • Heavy reliance on custom SVG rendering rather than pygal's higher-level chart patterns (inherent limitation for heatmaps in pygal)

Issues Found

  1. DE-01 MODERATE: Aesthetic sophistication good but not publication-level
    • Fix: Add thin semi-transparent horizontal lines between pitch class rows to improve visual grouping and readability
  2. DE-03 MODERATE: Storytelling improved with chord labels but could be stronger
    • Fix: Consider adding a brief subtitle or annotation highlighting the harmonic progression pattern (I–V–vi–IV)
  3. VQ-05 MINOR: Left margin slightly oversized
    • Fix: Reduce the y-axis title offset from 240px to ~200px and margin_left from 280 to ~250 to reclaim canvas space

AI Feedback for Next Attempt

To reach 90+: (1) Add thin semi-transparent horizontal separator lines between pitch class rows for better visual grouping and readability. (2) Tighten left margin by reducing y-axis title offset and margin_left values. (3) Consider adding a subtle subtitle or small annotation indicating the I–V–vi–IV progression pattern to strengthen data storytelling. (4) These refinements would push DE-01 toward 6-7 and DE-02 toward 5, bringing the total above 90.

Verdict: REJECTED

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

🔧 Repair Attempt 3/3

Applied fixes based on AI review feedback.

Status: Repair completed, re-triggering review...


🤖 impl-repair

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Mar 23, 2026

AI Review - Attempt 3/3

Image Description

The plot displays a chromagram heatmap using an inferno-inspired sequential colormap (dark purple/black for low energy through orange/yellow for high energy). The Y-axis shows all 12 pitch classes from C at the bottom to B at the top, labeled "Pitch Class" in bold. The X-axis shows time from 0.0 to ~7.9 seconds, labeled "Time (seconds)". A vertical colorbar on the right labeled "Energy" shows the 0.0–1.0 scale. Four chord regions are annotated above the heatmap in italic bold: "C major", "G major", "A minor", "F major", separated by dashed vertical lines. A subtitle below reads "Chord progression: I – V – vi – IV (C major key)". The chord tones are clearly visible as bright yellow/orange bands in their respective time regions (C/E/G bright in C major section, G/B/D in G major, A/C/E in A minor, F/A/C in F major), with smooth transitions between chord boundaries. Non-chord tones remain dark purple/black. The title reads "heatmap-chromagram · pygal · pyplots.ai".

Score: 91/100

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

Visual Quality (29/30)

  • VQ-01: Text Legibility (8/8) - All font sizes explicitly set: title 64px, axis titles 48px, pitch labels dynamically sized with min(44, cell_h*0.6), time labels 36px, colorbar labels 36px, chord labels 38px. All clearly readable.
  • VQ-02: No Overlap (6/6) - No overlapping text. Pitch labels well-spaced vertically, time labels use step=max(1, n_cols//10) to prevent crowding, chord region labels centered above their sections.
  • VQ-03: Element Visibility (6/6) - Heatmap cells are well-sized at 80 columns × 12 rows. Color differentiation between chord tones and non-chord tones is very clear. Smooth transitions visible.
  • VQ-04: Color Accessibility (4/4) - Inferno-inspired colormap is perceptually uniform and colorblind-safe. Strong contrast between low (dark purple) and high (yellow) values.
  • VQ-05: Layout & Canvas (3/4) - Good utilization with heatmap filling most of the canvas. Colorbar and margins are well-proportioned. Slight right-side margin overhead for colorbar placement.
  • VQ-06: Axis Labels & Title (2/2) - "Time (seconds)" and "Pitch Class" are descriptive with units/context.

Design Excellence (16/20)

  • DE-01: Aesthetic Sophistication (6/8) - Strong design: custom inferno colormap with smooth interpolation, intentional typographic hierarchy (bold titles, italic chord labels, regular tick labels), clean white background. Clearly above defaults.
  • DE-02: Visual Refinement (5/6) - Default pygal chrome suppressed. Subtle white separators between pitch rows (opacity 0.3). Clean heatmap border. Dashed chord boundary separators. Generous whitespace. Well-polished details.
  • DE-03: Data Storytelling (5/6) - Excellent storytelling: chord region labels above heatmap, dashed separators at chord boundaries, alternating subtle background bands, subtitle explaining the I–V–vi–IV progression. Viewer immediately understands the harmonic structure.

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) - Correct heatmap showing pitch class energy distribution over time.
  • SC-02: Required Features (4/4) - All 12 pitch classes on Y-axis, sequential colormap (inferno), colorbar with energy scale, time axis in seconds, 80-frame resolution captures chord transitions, realistic harmonic patterns.
  • SC-03: Data Mapping (3/3) - X=time, Y=pitch class, color=energy. All correctly mapped and visible.
  • SC-04: Title & Legend (3/3) - Title format "heatmap-chromagram · pygal · pyplots.ai" correct. No legend needed (colorbar serves as scale indicator).

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) - Shows four distinct chords with clear harmonic content, smooth transitions between chords, low background noise on non-chord tones, varying energy intensities within chord tones.
  • DQ-02: Realistic Context (5/5) - I–V–vi–IV is one of the most common chord progressions in popular music. Music chromagram analysis is a real MIR application. Neutral, educational topic.
  • DQ-03: Appropriate Scale (4/4) - Energy 0–1 is standard for normalized chroma features. 80 frames × 0.1s = 8 seconds is realistic for a short musical passage.

Code Quality (8/10)

  • CQ-01: KISS Structure (2/3) - Uses a class extending pygal's Graph, which is the required pattern for custom chart types in pygal. Justified but adds structural complexity.
  • CQ-02: Reproducibility (2/2) - np.random.seed(42) set.
  • CQ-03: Clean Imports (2/2) - All imports used: numpy for data, sys for path workaround, pygal Graph and Style.
  • CQ-04: Code Elegance (1/2) - Well-organized overall, but the sys.path manipulation workaround adds code smell. The class is well-structured internally.
  • CQ-05: Output & API (1/1) - Saves plot.png via render_to_png(), also creates SVG and HTML. Current pygal API.

Library Mastery (8/10)

  • LM-01: Idiomatic Usage (4/5) - Extends pygal's Graph base class correctly, overrides _plot() and _compute(), uses pygal's SVG node system (self.svg.node), Style configuration, and render pipeline. Advanced idiomatic pattern.
  • LM-02: Distinctive Features (4/5) - Graph subclass extension pattern is unique to pygal. Native SVG <title> tooltips, pygal's view coordinate system, and the render-to-multiple-formats pipeline are all pygal-distinctive features.

Score Caps Applied

  • None applied

Strengths

  • Excellent data storytelling with chord region labels, dashed separators, and subtitle explaining the harmonic progression
  • Strong inferno-inspired colormap with smooth interpolation, perceptually uniform and colorblind-safe
  • Advanced pygal usage extending the Graph base class with custom _plot() rendering
  • Native pygal SVG tooltips via <title> elements on each cell
  • All 12 pitch classes clearly labeled, realistic I–V–vi–IV chord progression data
  • Clean multi-format output (PNG, SVG, HTML)

Weaknesses

  • sys.path manipulation is a code workaround that adds complexity (though necessary for pygal name collision)
  • Class-based structure deviates from KISS ideal (though required by pygal's architecture)

Issues Found

None critical — implementation meets all quality thresholds.

AI Feedback for Next Attempt

N/A — implementation approved at 91/100. Strong chromagram visualization with excellent data storytelling and advanced pygal usage.

Verdict: APPROVED

@github-actions github-actions Bot added quality:91 Quality score 91/100 ai-approved Quality OK, ready for merge labels Mar 23, 2026
@github-actions github-actions Bot merged commit 95ba68b into main Mar 23, 2026
3 checks passed
@github-actions github-actions Bot deleted the implementation/heatmap-chromagram/pygal branch March 23, 2026 20:54
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 ai-attempt-2 Second repair attempt quality:85 Quality score 85/100 quality:86 Quality score 86/100 quality:91 Quality score 91/100

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants