From 576f5a2fb9388f391c189236eefbac0741e04436 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 3 Jun 2026 01:22:37 +0000 Subject: [PATCH 1/5] feat(pygal): implement waveform-audio MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Regen from quality 87. Addressed: - Canvas: 3200×1800 (was 4800×2700 — critical Step 0 violation) - Imprint palette applied: #009E73 waveform, #C475FD envelope, #AE3030 peak transient - Theme-adaptive chrome: ANYPLOT_THEME env var, correct #FAF8F1/#1A1A17 backgrounds - Correct title format: "waveform-audio · python · pygal · anyplot.ai" - Theme-suffixed output: plot-{THEME}.png / plot-{THEME}.html - Canonical font sizes: title=66, label=56, major_label=44, legend=44 - Peak transient dot enlarged to size 18 for better visibility against dense waveform - importlib.util workaround to prevent self-shadowing on cd-based execution --- .../implementations/python/pygal.py | 126 ++++++++++-------- 1 file changed, 72 insertions(+), 54 deletions(-) diff --git a/plots/waveform-audio/implementations/python/pygal.py b/plots/waveform-audio/implementations/python/pygal.py index 052bfbe905..594920653a 100644 --- a/plots/waveform-audio/implementations/python/pygal.py +++ b/plots/waveform-audio/implementations/python/pygal.py @@ -1,14 +1,45 @@ -""" pyplots.ai +"""anyplot.ai waveform-audio: Audio Waveform Plot -Library: pygal 3.1.0 | Python 3.14.3 -Quality: 87/100 | Created: 2026-03-07 +Library: pygal | Python 3.13 +Quality: pending | Created: 2026-06-03 """ +import importlib.util +import os +import sys + import numpy as np -import pygal -from pygal.style import Style +# Prevent this file (pygal.py) from shadowing the installed pygal package +_pygal_spec = importlib.util.find_spec("pygal") +if _pygal_spec and _pygal_spec.origin != __file__: + import pygal + from pygal.style import Style +else: + _cwd = sys.path.pop(0) + import pygal + from pygal.style import Style + + sys.path.insert(0, _cwd) + +# Theme tokens +THEME = os.getenv("ANYPLOT_THEME", "light") +PAGE_BG = "#FAF8F1" if THEME == "light" else "#1A1A17" +INK = "#1A1A17" if THEME == "light" else "#F0EFE8" +INK_MUTED = "#6B6A63" if THEME == "light" else "#A8A79F" + +# Series colors — Imprint palette position 1 for waveform; position 2 for envelope +# (lower envelope duplicates position 2 for visual continuity); semantic red for peak peak; +# neutral muted for zero reference line +CHART_COLORS = ( + "#009E73", # Waveform — Imprint position 1 + "#C475FD", # Decay envelope upper — Imprint position 2 + "#C475FD", # Decay envelope lower — matches upper for visual continuity + "#AE3030", # Peak transient — semantic red (maximum amplitude marker) + INK_MUTED, # Zero reference line — neutral chrome +) + # Data - synthesized A3 note (220 Hz) with harmonics and decay envelope np.random.seed(42) sample_rate = 44100 @@ -28,14 +59,14 @@ amplitude = signal * envelope amplitude = amplitude / np.max(np.abs(amplitude)) * 0.92 -# Downsample for pygal SVG rendering - enough points for smooth waveform +# Downsample for pygal SVG rendering — enough points for smooth waveform shape n_points = 1200 indices = np.linspace(0, len(t) - 1, n_points, dtype=int) t_down = t[indices] amp_down = amplitude[indices] env_down = envelope[indices] / np.max(np.abs(envelope)) * 0.92 -# Build XY data with per-point dict format for rich tooltips (pygal distinctive feature) +# Per-point dict format for rich interactive tooltips — pygal-distinctive feature waveform_data = [ { "value": (round(float(t_down[i]), 5), round(float(amp_down[i]), 4)), @@ -44,11 +75,10 @@ for i in range(n_points) ] -# Envelope curves with per-point labels for interactive exploration envelope_upper = [ { "value": (round(float(t_down[i]), 5), round(float(env_down[i]), 4)), - "label": f"envelope: ±{float(env_down[i]):.3f}", + "label": f"envelope: +{float(env_down[i]):.3f}", } for i in range(n_points) ] @@ -60,7 +90,7 @@ for i in range(n_points) ] -# Peak amplitude marker - highlight the attack transient peak for data storytelling +# Peak amplitude marker — highlights the attack transient peak_idx = int(np.argmax(np.abs(amp_down))) peak_marker = [ { @@ -69,54 +99,51 @@ } ] -# Style - publication quality with colorblind-safe palette -# Using blue (#306998) + orange (#E69F00) - universally distinguishable +# Zero reference line +zero_line = [ + {"value": (0.0, 0.0), "label": "zero baseline"}, + {"value": (round(float(t_down[-1]), 5), 0.0), "label": "zero baseline"}, +] + +# Title — 44 chars, under 67-char baseline, so default font size applies +title = "waveform-audio · python · pygal · anyplot.ai" + custom_style = Style( - background="white", - plot_background="#f5f6f8", - foreground="#2a2a2a", - foreground_strong="#1a1a1a", - foreground_subtle="#d0d0d0", - colors=("#306998", "#E69F00", "#E69F00", "#306998", "#999999"), - title_font_size=62, - label_font_size=40, - major_label_font_size=36, - legend_font_size=34, - value_font_size=28, - tooltip_font_size=28, - stroke_width=1.8, + background=PAGE_BG, + plot_background=PAGE_BG, + foreground=INK, + foreground_strong=INK, + foreground_subtle=INK_MUTED, + colors=CHART_COLORS, + title_font_size=66, + label_font_size=56, + major_label_font_size=44, + legend_font_size=44, + value_font_size=36, + stroke_width=2.5, opacity=0.65, opacity_hover=0.95, - title_font_family="sans-serif", - label_font_family="sans-serif", - major_label_font_family="sans-serif", - legend_font_family="sans-serif", - value_font_family="sans-serif", transition="200ms ease-in", ) -# X-axis labels - fewer ticks to avoid crowding x_labels = [round(i * 0.02, 2) for i in range(8)] -# Chart with comprehensive pygal configuration chart = pygal.XY( - width=4800, - height=2700, + width=3200, + height=1800, style=custom_style, - title="waveform-audio \u00b7 pygal \u00b7 pyplots.ai", + title=title, x_title="Time (s)", y_title="Amplitude", show_dots=False, fill=True, - stroke_style={"width": 1.8}, + stroke_style={"width": 2.5}, show_legend=True, legend_at_bottom=True, - legend_box_size=30, + legend_box_size=36, range=(-1.0, 1.0), show_x_guides=False, show_y_guides=True, - x_label_rotation=0, - truncate_label=-1, x_labels=x_labels, x_labels_major_every=1, x_value_formatter=lambda x: f"{x:.2f}", @@ -128,16 +155,12 @@ margin_right=40, spacing=25, show_minor_x_labels=False, - dots_size=0, explicit_size=True, js=[], - secondary_range=(-1.0, 1.0), interpolate="cubic", ) chart.add("Waveform", waveform_data) - -# Envelope lines showing decay boundary - thick dashed for strong visibility chart.add( "Decay envelope", envelope_upper, @@ -152,17 +175,12 @@ show_dots=False, fill=False, ) - -# Peak transient marker - distinctive pygal per-point styling with custom node -chart.add("Peak transient", peak_marker, stroke_style={"width": 0}, dots_size=12, show_dots=True, fill=False) - -# Zero reference line -zero_line = [ - {"value": (0.0, 0), "label": "zero baseline"}, - {"value": (round(float(t_down[-1]), 5), 0), "label": "zero baseline"}, -] +# Peak transient — larger dot (18) for visibility against dense waveform +chart.add("Peak transient", peak_marker, stroke_style={"width": 0}, dots_size=18, show_dots=True, fill=False) chart.add(None, zero_line, stroke_style={"width": 1.5, "dasharray": "4,6"}, show_dots=False, fill=False) # Save -chart.render_to_png("plot.png") -chart.render_to_file("plot.html") +chart.render_to_png(f"plot-{THEME}.png") + +with open(f"plot-{THEME}.html", "wb") as f: + f.write(chart.render()) From 16db6c3a532f4ee554b496f39438a6ccd680c7ba Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 3 Jun 2026 01:25:03 +0000 Subject: [PATCH 2/5] chore(pygal): add metadata for waveform-audio --- .../waveform-audio/metadata/python/pygal.yaml | 233 ++---------------- 1 file changed, 15 insertions(+), 218 deletions(-) diff --git a/plots/waveform-audio/metadata/python/pygal.yaml b/plots/waveform-audio/metadata/python/pygal.yaml index cffecd115a..3d1382e679 100644 --- a/plots/waveform-audio/metadata/python/pygal.yaml +++ b/plots/waveform-audio/metadata/python/pygal.yaml @@ -1,224 +1,21 @@ +# Per-library metadata for pygal implementation of waveform-audio +# Auto-generated by impl-generate.yml + library: pygal +language: python specification_id: waveform-audio created: '2026-03-07T14:58:06Z' -updated: '2026-03-07T15:35:37Z' -generated_by: claude-opus-4-5-20251101 -workflow_run: 22801238622 +updated: '2026-06-03T01:25:03Z' +generated_by: claude-sonnet +workflow_run: 26857545980 issue: 4563 -python_version: 3.14.3 +language_version: 3.13.13 library_version: 3.1.0 -preview_url: https://storage.googleapis.com/anyplot-images/plots/waveform-audio/pygal/plot.png -preview_html: https://storage.googleapis.com/anyplot-images/plots/waveform-audio/pygal/plot.html -quality_score: 87 +preview_url_light: https://storage.googleapis.com/anyplot-images/plots/waveform-audio/python/pygal/plot-light.png +preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/waveform-audio/python/pygal/plot-dark.png +preview_html_light: https://storage.googleapis.com/anyplot-images/plots/waveform-audio/python/pygal/plot-light.html +preview_html_dark: https://storage.googleapis.com/anyplot-images/plots/waveform-audio/python/pygal/plot-dark.html +quality_score: null review: - strengths: - - 'Excellent spec compliance: all required features present (filled area, zero-line, - envelope, symmetric y-range)' - - Strong data storytelling with peak transient marker and decay envelope creating - clear narrative - - Colorblind-safe palette (blue + orange) with good contrast - - Leverages pygal-specific per-point dict format for rich interactive tooltips - - Clean KISS code structure with realistic audio data (A3 note, 220Hz + harmonics) - weaknesses: - - DE-02 limited by pygal inability to remove plot frame/spines — box border still - visible - - Peak transient marker is small relative to the dense waveform - - DE-01 could benefit from more refined typography/color treatment for publication - quality - image_description: The plot displays an audio waveform of a synthesized A3 note - (220 Hz) with harmonics over approximately 0.15 seconds. The waveform is rendered - as a blue filled area symmetric around the zero baseline, showing dense oscillations - with a clear attack transient near t=0.01s followed by exponential decay. An orange - dashed line traces the decay envelope both above and below the waveform. A dark - blue dot marks the peak transient at maximum amplitude (~0.92). The background - is white with a light gray (#f5f6f8) plot area and subtle horizontal y-axis grid - lines. The x-axis shows "Time (s)" from 0.00 to 0.14+, and the y-axis shows "Amplitude" - from -1.000 to 1.000. The legend at the bottom lists "Waveform", "Decay envelope", - and "Peak transient". The title reads "waveform-audio · pygal · pyplots.ai". - criteria_checklist: - visual_quality: - score: 28 - max: 30 - items: - - id: VQ-01 - name: Text Legibility - score: 7 - max: 8 - passed: true - comment: All font sizes explicitly set (title=62, label=40, major_label=36, - legend=34); all text clearly readable - - id: VQ-02 - name: No Overlap - score: 6 - max: 6 - passed: true - comment: No overlapping text; x-axis labels well-spaced, legend at bottom - clear - - id: VQ-03 - name: Element Visibility - score: 5 - max: 6 - passed: true - comment: Waveform clearly rendered with 1200 points; envelope visible; peak - dot small but identifiable - - id: VQ-04 - name: Color Accessibility - score: 4 - max: 4 - passed: true - comment: Blue (#306998) + orange (#E69F00) colorblind-safe palette with good - contrast - - id: VQ-05 - name: Layout & Canvas - score: 4 - max: 4 - passed: true - comment: Plot fills canvas well with balanced margins - - id: VQ-06 - name: Axis Labels & Title - score: 2 - max: 2 - passed: true - comment: Time (s) with units, Amplitude appropriate for normalized signal - design_excellence: - score: 12 - max: 20 - items: - - id: DE-01 - name: Aesthetic Sophistication - score: 5 - max: 8 - passed: true - comment: Custom colorblind-safe palette, light gray plot background, intentional - font hierarchy; above defaults but not publication-ready - - id: DE-02 - name: Visual Refinement - score: 3 - max: 6 - passed: true - comment: Y-guides only, subtle grid, but pygal default box frame still visible - - id: DE-03 - name: Data Storytelling - score: 4 - max: 6 - passed: true - comment: Peak transient marker and decay envelope create visual hierarchy - and attack-decay narrative - spec_compliance: - score: 15 - max: 15 - items: - - id: SC-01 - name: Plot Type - score: 5 - max: 5 - passed: true - comment: Correct XY waveform visualization - - id: SC-02 - name: Required Features - score: 4 - max: 4 - passed: true - comment: 'All spec features present: filled area, zero-line, envelope, symmetric - y-range, synthetic audio' - - id: SC-03 - name: Data Mapping - score: 3 - max: 3 - passed: true - comment: X=time, Y=amplitude, axes show full range - - id: SC-04 - name: Title & Legend - score: 3 - max: 3 - passed: true - comment: Title format correct, legend labels descriptive and match data - data_quality: - score: 15 - max: 15 - items: - - id: DQ-01 - name: Feature Coverage - score: 6 - max: 6 - passed: true - comment: Shows attack transient, harmonic content, exponential decay, both - polarities, envelope boundary - - id: DQ-02 - name: Realistic Context - score: 5 - max: 5 - passed: true - comment: A3 note (220 Hz) with harmonics is a real-world audio scenario - - id: DQ-03 - name: Appropriate Scale - score: 4 - max: 4 - passed: true - comment: 220Hz fundamental, 0.15s duration, 44.1kHz sample rate, normalized - amplitude - code_quality: - score: 10 - max: 10 - items: - - id: CQ-01 - name: KISS Structure - score: 3 - max: 3 - passed: true - comment: 'Linear flow: imports, data generation, style, chart, save' - - id: CQ-02 - name: Reproducibility - score: 2 - max: 2 - passed: true - comment: np.random.seed(42) set; data deterministic via sine functions - - id: CQ-03 - name: Clean Imports - score: 2 - max: 2 - passed: true - comment: numpy, pygal, Style — all used - - id: CQ-04 - name: Code Elegance - score: 2 - max: 2 - passed: true - comment: Appropriate complexity; per-point dict format leverages pygal features - - id: CQ-05 - name: Output & API - score: 1 - max: 1 - passed: true - comment: Saves as plot.png via render_to_png - library_mastery: - score: 7 - max: 10 - items: - - id: LM-01 - name: Idiomatic Usage - score: 4 - max: 5 - passed: true - comment: Good use of pygal XY chart, Style class, fill, stroke_style, legend - config, cubic interpolation - - id: LM-02 - name: Distinctive Features - score: 3 - max: 5 - passed: true - comment: Per-point dict format with custom labels for rich tooltips, HTML - export, stroke_style with dasharray - verdict: REJECTED -impl_tags: - dependencies: [] - techniques: - - hover-tooltips - - html-export - patterns: - - data-generation - dataprep: - - normalization - styling: - - alpha-blending - - grid-styling + strengths: [] + weaknesses: [] From 0e15c67a6233a9d4dcc5bae299cb72d2695b4df8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 3 Jun 2026 01:32:36 +0000 Subject: [PATCH 3/5] chore(pygal): update quality score 89 and review feedback for waveform-audio --- .../implementations/python/pygal.py | 6 +- .../waveform-audio/metadata/python/pygal.yaml | 273 +++++++++++++++++- 2 files changed, 269 insertions(+), 10 deletions(-) diff --git a/plots/waveform-audio/implementations/python/pygal.py b/plots/waveform-audio/implementations/python/pygal.py index 594920653a..e532848fab 100644 --- a/plots/waveform-audio/implementations/python/pygal.py +++ b/plots/waveform-audio/implementations/python/pygal.py @@ -1,7 +1,7 @@ -"""anyplot.ai +""" anyplot.ai waveform-audio: Audio Waveform Plot -Library: pygal | Python 3.13 -Quality: pending | Created: 2026-06-03 +Library: pygal 3.1.0 | Python 3.13.13 +Quality: 89/100 | Updated: 2026-06-03 """ import importlib.util diff --git a/plots/waveform-audio/metadata/python/pygal.yaml b/plots/waveform-audio/metadata/python/pygal.yaml index 3d1382e679..632ca1a283 100644 --- a/plots/waveform-audio/metadata/python/pygal.yaml +++ b/plots/waveform-audio/metadata/python/pygal.yaml @@ -1,11 +1,8 @@ -# Per-library metadata for pygal implementation of waveform-audio -# Auto-generated by impl-generate.yml - library: pygal language: python specification_id: waveform-audio created: '2026-03-07T14:58:06Z' -updated: '2026-06-03T01:25:03Z' +updated: '2026-06-03T01:32:36Z' generated_by: claude-sonnet workflow_run: 26857545980 issue: 4563 @@ -15,7 +12,269 @@ preview_url_light: https://storage.googleapis.com/anyplot-images/plots/waveform- preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/waveform-audio/python/pygal/plot-dark.png preview_html_light: https://storage.googleapis.com/anyplot-images/plots/waveform-audio/python/pygal/plot-light.html preview_html_dark: https://storage.googleapis.com/anyplot-images/plots/waveform-audio/python/pygal/plot-dark.html -quality_score: null +quality_score: 89 review: - strengths: [] - weaknesses: [] + strengths: + - 'Correct Imprint palette with semantic intent: green waveform (#009E73, position + 1), purple envelope (#C475FD, position 2), semantic red peak transient (#AE3030) + — all applied correctly' + - 'Highly idiomatic pygal usage: per-point dict format with rich labels, multiple + stroke_style configurations (dashed envelope, thick peak dot), x_value_formatter, + cubic interpolation, and legend_at_bottom' + - 'Full spec compliance: filled area waveform, semi-transparent opacity (0.65), + decay envelope (upper + lower dashed), peak transient marker, zero reference line, + synthetic A3 note data, correct axis ranges' + - 'Both themes render correctly: warm off-white light background (#FAF8F1) and warm + near-black dark background (#1A1A17), with all text readable in both renders — + no dark-on-dark failures' + - Interactive HTML output alongside PNG, making full use of pygal's interactive + nature + - 'Realistic audio domain: physically accurate 220 Hz A3 note with harmonics and + exponential decay, np.random.seed(42) for reproducibility' + - 'Clean code structure: flat script, all imports used, proper importlib workaround + for filename collision with the installed pygal package' + weaknesses: + - 'DE-01 (Aesthetic Sophistication 5/8): Chart retains the default pygal frame/border. + Consider increasing margin_top/margin_bottom/margin_left/margin_right for more + breathing room, and explore whether `no_data_text`, `inner_radius`, or style tweaks + can give a more polished, less boxy look. A custom font family or refined typographic + touches would elevate from ''well-configured library default'' to ''strong design''.' + - 'DE-02 (Visual Refinement 3/6): The zero reference dashed line (INK_MUTED colored) + may be partially obscured by the green waveform fill since it shares the same + canvas layer. Adding it first before the waveform series, or using a slightly + different approach to ensure it''s rendered above the fill, would make it more + prominent. Also consider slightly increasing margins for more generous whitespace.' + - 'VQ-03 (Element Visibility 5/6): The zero reference dashed line (INK_MUTED, width=1.5) + is subtle and may not be clearly distinguishable within the waveform fill area. + Adding it as the first series (before the waveform fill) so pygal renders it on + top, or increasing its stroke width slightly, would improve its visibility.' + image_description: |- + Light render (plot-light.png): + Background: Warm off-white (#FAF8F1) — correctly matches the light theme surface. Not pure white. + Chrome: Title "waveform-audio · python · pygal · anyplot.ai" clearly visible in dark ink at top center (~50-55% of canvas width). Y-axis label "Amplitude" vertical on left, X-axis label "Time (s)" below plot — both readable. Y-axis tick labels (-1.000, -0.800, ... 1.000) and X-axis ticks (0.00, 0.02, ... 0.14) readable. Legend at bottom shows "Waveform" (green swatch), "Decay envelope" (purple swatch), "Peak transient" (red swatch) — all clear. + Data: Green (#009E73) filled area waveform with semi-transparent fill (opacity 0.65) shows an audio waveform decaying from left to right. Attack phase with peak near x=0.01s. Purple (#C475FD) dashed envelope lines trace the upper and lower amplitude bounds. A red dot (#AE3030) marks the peak transient near x=0.01s at the top of the waveform. Subtle Y-axis grid lines visible. Zero crossing clearly visible through waveform oscillation (dashed INK_MUTED zero reference line is present but subtle within the fill). + Legibility verdict: PASS — all text readable; first series is #009E73 (brand green); background is correct #FAF8F1. + + Dark render (plot-dark.png): + Background: Warm near-black (#1A1A17) — correctly matches the dark theme surface. Not pure black. + Chrome: Title visible in light text (near #F0EFE8) against dark background — clearly readable. Axis labels "Amplitude" and "Time (s)" visible in light text. Y-axis and X-axis tick labels rendered in light color — all readable. Legend at bottom shows same three entries with identical swatches. No dark-on-dark failures observed. + Data: Data colors are identical to light render — waveform in #009E73 green, envelope in #C475FD purple, peak transient dot in #AE3030 red. The decaying waveform shape, envelope bounds, and peak marker all appear in the same positions with the same colors as the light render. Only the background and chrome have flipped. + Legibility verdict: PASS — all text readable against dark background; data colors identical to light render; no dark-on-dark text failures. + criteria_checklist: + visual_quality: + score: 28 + max: 30 + items: + - id: VQ-01 + name: Text Legibility + score: 7 + max: 8 + passed: true + comment: All font sizes explicitly set per library spec (title=66, label=56, + major_label=44, legend=44). All text readable in both light and dark renders. + Y-axis ticks with 3 decimal places are slightly verbose but readable. Proportions + good. + - id: VQ-02 + name: No Overlap + score: 6 + max: 6 + passed: true + comment: No text or element overlap in either render. + - id: VQ-03 + name: Element Visibility + score: 5 + max: 6 + passed: true + comment: Waveform fill and peak transient dot clearly visible. Zero reference + dashed line (INK_MUTED, width=1.5) may be partially obscured beneath the + waveform fill in the central area. + - id: VQ-04 + name: Color Accessibility + score: 2 + max: 2 + passed: true + comment: Imprint palette is CVD-safe. Green/purple/red are distinguishable + under deuteranopia simulation. Semi-transparent fill maintains visibility. + - id: VQ-05 + name: Layout & Canvas + score: 4 + max: 4 + passed: true + comment: 3200x1800 landscape canvas. Canvas gate passed. Good margins (top=50, + bottom=70, left=80, right=40). No clipping. No AR-09 trigger. + - id: VQ-06 + name: Axis Labels & Title + score: 2 + max: 2 + passed: true + comment: 'Title matches required format exactly. X-axis: ''Time (s)'' with + unit. Y-axis: ''Amplitude'' descriptive.' + - id: VQ-07 + name: Palette Compliance + score: 2 + max: 2 + passed: true + comment: 'First series #009E73 (brand green). Second series #C475FD (Imprint + position 2). Semantic red #AE3030 for peak transient (appropriate semantic + exception). INK_MUTED for zero reference (theme-adaptive neutral anchor). + Backgrounds #FAF8F1/#1A1A17 correct. Data colors identical across both renders.' + design_excellence: + score: 12 + max: 20 + items: + - id: DE-01 + name: Aesthetic Sophistication + score: 5 + max: 8 + passed: true + comment: Multi-layer design with intentional semantic color assignment (green + waveform, purple envelope, semantic red peak). Cubic interpolation for smooth + rendering. Above 4/8 default but retains default pygal frame styling — not + yet at 6/8 strong design level. + - id: DE-02 + name: Visual Refinement + score: 3 + max: 6 + passed: true + comment: Semi-transparent fill (opacity=0.65). Y-axis grid only (no X guides). + Dashed stroke styles for envelope and zero reference. show_dots=False for + dense waveform. One point above default (2) for clear refinements. + - id: DE-03 + name: Data Storytelling + score: 4 + max: 6 + passed: true + comment: 'Clear visual hierarchy: waveform (primary green) > envelope (secondary + dashed purple) > peak transient (semantic red dot accent). The red peak + dot immediately draws the viewer''s eye to the attack transient. Decay envelope + guides reading of the dynamics. Two points above default (2).' + spec_compliance: + score: 15 + max: 15 + items: + - id: SC-01 + name: Plot Type + score: 5 + max: 5 + passed: true + comment: Correct audio waveform plot using filled XY area chart showing positive + and negative amplitude symmetric around zero. + - id: SC-02 + name: Required Features + score: 4 + max: 4 + passed: true + comment: Filled area with semi-transparent opacity, zero reference line, time + X-axis, amplitude Y-axis range (-1 to +1), decay envelope (upper+lower), + peak transient marker, synthetic audio data. + - id: SC-03 + name: Data Mapping + score: 3 + max: 3 + passed: true + comment: Time on X-axis in seconds, normalized amplitude on Y-axis, all data + visible. + - id: SC-04 + name: Title & Legend + score: 3 + max: 3 + passed: true + comment: Title 'waveform-audio · python · pygal · anyplot.ai' matches required + format exactly. Legend shows Waveform, Decay envelope, Peak transient with + correct color swatches. + data_quality: + score: 15 + max: 15 + items: + - id: DQ-01 + name: Feature Coverage + score: 6 + max: 6 + passed: true + comment: Shows waveform oscillation with attack and decay dynamics, envelope + bounds, peak transient identification, and zero reference baseline — comprehensive + coverage of audio waveform features. + - id: DQ-02 + name: Realistic Context + score: 5 + max: 5 + passed: true + comment: A3 musical note (220 Hz fundamental) with harmonics (2nd, 3rd, 5th) + and physically accurate exponential decay. Neutral topic (music/acoustics). + Scientifically plausible audio physics. + - id: DQ-03 + name: Appropriate Scale + score: 4 + max: 4 + passed: true + comment: 44100 Hz sample rate (CD quality), 0.15 second duration (short clip), + normalized amplitude -1 to +1. All values correct for audio domain. + code_quality: + score: 10 + max: 10 + items: + - id: CQ-01 + name: KISS Structure + score: 3 + max: 3 + passed: true + comment: 'Flat script: importlib workaround → data generation → chart configuration + → save. No functions or classes beyond necessary workaround.' + - id: CQ-02 + name: Reproducibility + score: 2 + max: 2 + passed: true + comment: np.random.seed(42) set. + - id: CQ-03 + name: Clean Imports + score: 2 + max: 2 + passed: true + comment: importlib.util, os, sys, numpy, pygal, Style — all used. + - id: CQ-04 + name: Code Elegance + score: 2 + max: 2 + passed: true + comment: Clean, no fake UI elements. The importlib workaround is necessary + and explained. + - id: CQ-05 + name: Output & API + score: 1 + max: 1 + passed: true + comment: Saves plot-{THEME}.png and plot-{THEME}.html correctly. + library_mastery: + score: 9 + max: 10 + items: + - id: LM-01 + name: Idiomatic Usage + score: 5 + max: 5 + passed: true + comment: 'Highly idiomatic: Style object, per-point dict format, stroke_style + per series, x_value_formatter, value_formatter, explicit_size, legend_at_bottom, + cubic interpolation, js=[] for PNG mode.' + - id: LM-02 + name: Distinctive Features + score: 4 + max: 5 + passed: true + comment: 'Per-point dict format {value: (...), label: ''...''} is pygal-distinctive, + enabling rich interactive tooltips in the HTML output. HTML alongside PNG + makes full use of pygal''s interactive SVG nature. Cubic interpolation and + series-level stroke_style customization also showcase pygal capabilities.' + verdict: REJECTED +impl_tags: + dependencies: [] + techniques: + - html-export + - hover-tooltips + patterns: + - data-generation + dataprep: + - normalization + styling: + - alpha-blending From 78ad260980b0862225bf35f12297e0a7953c031e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 3 Jun 2026 01:43:11 +0000 Subject: [PATCH 4/5] fix(pygal): address review feedback for waveform-audio Attempt 1/3 - fixes based on AI review --- .../waveform-audio/implementations/python/pygal.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/plots/waveform-audio/implementations/python/pygal.py b/plots/waveform-audio/implementations/python/pygal.py index e532848fab..e848d359b8 100644 --- a/plots/waveform-audio/implementations/python/pygal.py +++ b/plots/waveform-audio/implementations/python/pygal.py @@ -1,4 +1,4 @@ -""" anyplot.ai +"""anyplot.ai waveform-audio: Audio Waveform Plot Library: pygal 3.1.0 | Python 3.13.13 Quality: 89/100 | Updated: 2026-06-03 @@ -149,10 +149,10 @@ x_value_formatter=lambda x: f"{x:.2f}", value_formatter=lambda x: f"{x:.3f}", print_values=False, - margin_top=50, - margin_bottom=70, - margin_left=80, - margin_right=40, + margin_top=80, + margin_bottom=100, + margin_left=100, + margin_right=60, spacing=25, show_minor_x_labels=False, explicit_size=True, @@ -177,7 +177,9 @@ ) # Peak transient — larger dot (18) for visibility against dense waveform chart.add("Peak transient", peak_marker, stroke_style={"width": 0}, dots_size=18, show_dots=True, fill=False) -chart.add(None, zero_line, stroke_style={"width": 1.5, "dasharray": "4,6"}, show_dots=False, fill=False) +chart.add( + None, zero_line, stroke_style={"width": 3.0, "dasharray": "10,5", "linecap": "round"}, show_dots=False, fill=False +) # Save chart.render_to_png(f"plot-{THEME}.png") From ffef1979d1b614dc94c80f2a0569da266c4f0444 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 3 Jun 2026 01:50:44 +0000 Subject: [PATCH 5/5] chore(pygal): update quality score 87 and review feedback for waveform-audio --- .../implementations/python/pygal.py | 4 +- .../waveform-audio/metadata/python/pygal.yaml | 190 ++++++++---------- 2 files changed, 84 insertions(+), 110 deletions(-) diff --git a/plots/waveform-audio/implementations/python/pygal.py b/plots/waveform-audio/implementations/python/pygal.py index e848d359b8..6dc574b6a4 100644 --- a/plots/waveform-audio/implementations/python/pygal.py +++ b/plots/waveform-audio/implementations/python/pygal.py @@ -1,7 +1,7 @@ -"""anyplot.ai +""" anyplot.ai waveform-audio: Audio Waveform Plot Library: pygal 3.1.0 | Python 3.13.13 -Quality: 89/100 | Updated: 2026-06-03 +Quality: 87/100 | Updated: 2026-06-03 """ import importlib.util diff --git a/plots/waveform-audio/metadata/python/pygal.yaml b/plots/waveform-audio/metadata/python/pygal.yaml index 632ca1a283..7146a30197 100644 --- a/plots/waveform-audio/metadata/python/pygal.yaml +++ b/plots/waveform-audio/metadata/python/pygal.yaml @@ -2,7 +2,7 @@ library: pygal language: python specification_id: waveform-audio created: '2026-03-07T14:58:06Z' -updated: '2026-06-03T01:32:36Z' +updated: '2026-06-03T01:50:43Z' generated_by: claude-sonnet workflow_run: 26857545980 issue: 4563 @@ -12,54 +12,42 @@ preview_url_light: https://storage.googleapis.com/anyplot-images/plots/waveform- preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/waveform-audio/python/pygal/plot-dark.png preview_html_light: https://storage.googleapis.com/anyplot-images/plots/waveform-audio/python/pygal/plot-light.html preview_html_dark: https://storage.googleapis.com/anyplot-images/plots/waveform-audio/python/pygal/plot-dark.html -quality_score: 89 +quality_score: 87 review: strengths: - - 'Correct Imprint palette with semantic intent: green waveform (#009E73, position - 1), purple envelope (#C475FD, position 2), semantic red peak transient (#AE3030) - — all applied correctly' - - 'Highly idiomatic pygal usage: per-point dict format with rich labels, multiple - stroke_style configurations (dashed envelope, thick peak dot), x_value_formatter, - cubic interpolation, and legend_at_bottom' - - 'Full spec compliance: filled area waveform, semi-transparent opacity (0.65), - decay envelope (upper + lower dashed), peak transient marker, zero reference line, - synthetic A3 note data, correct axis ranges' - - 'Both themes render correctly: warm off-white light background (#FAF8F1) and warm - near-black dark background (#1A1A17), with all text readable in both renders — - no dark-on-dark failures' - - Interactive HTML output alongside PNG, making full use of pygal's interactive - nature - - 'Realistic audio domain: physically accurate 220 Hz A3 note with harmonics and - exponential decay, np.random.seed(42) for reproducibility' - - 'Clean code structure: flat script, all imports used, proper importlib workaround - for filename collision with the installed pygal package' + - 'Perfect spec compliance: fills all required features (filled waveform, zero-line, + semi-transparent fill, envelope, time axis, normalized amplitude)' + - 'Excellent data quality: physically realistic A3 musical note with harmonics and + exponential decay, appropriate scale' + - 'Flawless code quality: clean KISS structure, seeded for reproducibility, all + imports used, correct pygal API' + - 'Correct Imprint palette usage: green waveform, purple envelope, semantic red + for peak transient' + - Both themes render correctly with proper chrome adaptation — no dark-on-dark failures + - 'Idiomatic pygal: per-point dict tooltips, cubic interpolation, explicit canvas + sizing' + - Interactive HTML output with rich per-point tooltip labels (time + amplitude for + each of 1200 points) weaknesses: - - 'DE-01 (Aesthetic Sophistication 5/8): Chart retains the default pygal frame/border. - Consider increasing margin_top/margin_bottom/margin_left/margin_right for more - breathing room, and explore whether `no_data_text`, `inner_radius`, or style tweaks - can give a more polished, less boxy look. A custom font family or refined typographic - touches would elevate from ''well-configured library default'' to ''strong design''.' - - 'DE-02 (Visual Refinement 3/6): The zero reference dashed line (INK_MUTED colored) - may be partially obscured by the green waveform fill since it shares the same - canvas layer. Adding it first before the waveform series, or using a slightly - different approach to ensure it''s rendered above the fill, would make it more - prominent. Also consider slightly increasing margins for more generous whitespace.' - - 'VQ-03 (Element Visibility 5/6): The zero reference dashed line (INK_MUTED, width=1.5) - is subtle and may not be clearly distinguishable within the waveform fill area. - Adding it as the first series (before the waveform fill) so pygal renders it on - top, or increasing its stroke width slightly, would improve its visibility.' + - Zero reference line is somewhat subtle behind the dense waveform fill — could + use a slightly higher stroke-width or INK color to stand out more clearly + - 'Design excellence is moderate: while the color hierarchy and dashed envelope + show intent, the chart retains pygal default box frame and does not push into + highly polished territory' + - 'Data storytelling is functional but not exceptional: no annotations beyond the + peak marker, envelope story is implicit rather than guided' image_description: |- Light render (plot-light.png): - Background: Warm off-white (#FAF8F1) — correctly matches the light theme surface. Not pure white. - Chrome: Title "waveform-audio · python · pygal · anyplot.ai" clearly visible in dark ink at top center (~50-55% of canvas width). Y-axis label "Amplitude" vertical on left, X-axis label "Time (s)" below plot — both readable. Y-axis tick labels (-1.000, -0.800, ... 1.000) and X-axis ticks (0.00, 0.02, ... 0.14) readable. Legend at bottom shows "Waveform" (green swatch), "Decay envelope" (purple swatch), "Peak transient" (red swatch) — all clear. - Data: Green (#009E73) filled area waveform with semi-transparent fill (opacity 0.65) shows an audio waveform decaying from left to right. Attack phase with peak near x=0.01s. Purple (#C475FD) dashed envelope lines trace the upper and lower amplitude bounds. A red dot (#AE3030) marks the peak transient near x=0.01s at the top of the waveform. Subtle Y-axis grid lines visible. Zero crossing clearly visible through waveform oscillation (dashed INK_MUTED zero reference line is present but subtle within the fill). - Legibility verdict: PASS — all text readable; first series is #009E73 (brand green); background is correct #FAF8F1. + Background: Warm off-white #FAF8F1 — correct light surface + Chrome: Title "waveform-audio · python · pygal · anyplot.ai" in dark ink — clearly readable. X-axis label "Time (s)" and Y-axis label "Amplitude" visible at appropriate sizes. Tick labels on both axes readable. Legend at bottom with "Waveform", "Decay envelope", "Peak transient" — all legible. + Data: Green (#009E73, Imprint pos 1) semi-transparent filled waveform showing oscillatory A3 note with decay. Purple (#C475FD, Imprint pos 2) dashed upper/lower envelope bounds. Red (#AE3030, semantic) dot marking peak transient at ~0.014s. Dashed gray zero-reference line at y=0. + Legibility verdict: PASS Dark render (plot-dark.png): - Background: Warm near-black (#1A1A17) — correctly matches the dark theme surface. Not pure black. - Chrome: Title visible in light text (near #F0EFE8) against dark background — clearly readable. Axis labels "Amplitude" and "Time (s)" visible in light text. Y-axis and X-axis tick labels rendered in light color — all readable. Legend at bottom shows same three entries with identical swatches. No dark-on-dark failures observed. - Data: Data colors are identical to light render — waveform in #009E73 green, envelope in #C475FD purple, peak transient dot in #AE3030 red. The decaying waveform shape, envelope bounds, and peak marker all appear in the same positions with the same colors as the light render. Only the background and chrome have flipped. - Legibility verdict: PASS — all text readable against dark background; data colors identical to light render; no dark-on-dark text failures. + Background: Warm near-black #1A1A17 — correct dark surface + Chrome: Title, axis labels, tick labels, and legend all flip to light text — clearly readable. No dark-on-dark failures detected. + Data: Identical data colors to light render — green waveform, purple envelope, red peak, gray zero line. Brand green #009E73 reads clearly on dark surface. + Legibility verdict: PASS criteria_checklist: visual_quality: score: 28 @@ -70,54 +58,48 @@ review: score: 7 max: 8 passed: true - comment: All font sizes explicitly set per library spec (title=66, label=56, - major_label=44, legend=44). All text readable in both light and dark renders. - Y-axis ticks with 3 decimal places are slightly verbose but readable. Proportions - good. + comment: Font sizes correctly set per pygal guide (title=66, label=56, major_label=44, + legend=44). Both renders fully legible. - id: VQ-02 name: No Overlap score: 6 max: 6 passed: true - comment: No text or element overlap in either render. + comment: Clean layout throughout. No collisions between text, data, or annotations. - id: VQ-03 name: Element Visibility score: 5 max: 6 passed: true - comment: Waveform fill and peak transient dot clearly visible. Zero reference - dashed line (INK_MUTED, width=1.5) may be partially obscured beneath the - waveform fill in the central area. + comment: Waveform fill, envelope dashed lines, and peak marker are visible. + Zero reference line somewhat subtle behind dense fill. - id: VQ-04 name: Color Accessibility score: 2 max: 2 passed: true - comment: Imprint palette is CVD-safe. Green/purple/red are distinguishable - under deuteranopia simulation. Semi-transparent fill maintains visibility. + comment: Imprint palette used correctly. CVD-safe green/purple/red combination. - id: VQ-05 name: Layout & Canvas score: 4 max: 4 passed: true - comment: 3200x1800 landscape canvas. Canvas gate passed. Good margins (top=50, - bottom=70, left=80, right=40). No clipping. No AR-09 trigger. + comment: Canvas 3200x1800 correct. Canvas gate passed. Generous margins, nothing + clipped. - id: VQ-06 name: Axis Labels & Title score: 2 max: 2 passed: true - comment: 'Title matches required format exactly. X-axis: ''Time (s)'' with - unit. Y-axis: ''Amplitude'' descriptive.' + comment: 'Title matches required format. X: Time (s), Y: Amplitude — descriptive + with units.' - id: VQ-07 name: Palette Compliance score: 2 max: 2 passed: true - comment: 'First series #009E73 (brand green). Second series #C475FD (Imprint - position 2). Semantic red #AE3030 for peak transient (appropriate semantic - exception). INK_MUTED for zero reference (theme-adaptive neutral anchor). - Backgrounds #FAF8F1/#1A1A17 correct. Data colors identical across both renders.' + comment: 'First series #009E73 correct. Imprint positions used. Backgrounds + #FAF8F1/#1A1A17 correct. Both renders theme-correct.' design_excellence: score: 12 max: 20 @@ -127,27 +109,25 @@ review: score: 5 max: 8 passed: true - comment: Multi-layer design with intentional semantic color assignment (green - waveform, purple envelope, semantic red peak). Cubic interpolation for smooth - rendering. Above 4/8 default but retains default pygal frame styling — not - yet at 6/8 strong design level. + comment: 'Above defaults. Intentional color hierarchy: green primary, purple + envelope, semantic red peak. Semi-transparent fill, cubic interpolation, + dashed envelope with round linecaps.' - id: DE-02 name: Visual Refinement score: 3 max: 6 passed: true - comment: Semi-transparent fill (opacity=0.65). Y-axis grid only (no X guides). - Dashed stroke styles for envelope and zero reference. show_dots=False for - dense waveform. One point above default (2) for clear refinements. + comment: Y-guides only (correct for waveform). Dashed stroke with custom dasharray + and round linecaps, opacity on fill. Pygal box frame present (expected for + library). - id: DE-03 name: Data Storytelling score: 4 max: 6 passed: true - comment: 'Clear visual hierarchy: waveform (primary green) > envelope (secondary - dashed purple) > peak transient (semantic red dot accent). The red peak - dot immediately draws the viewer''s eye to the attack transient. Decay envelope - guides reading of the dynamics. Two points above default (2).' + comment: Red peak marker creates clear focal point. Decay envelope provides + dynamic range context. Color hierarchy guides eye from primary signal to + boundary to extreme event. spec_compliance: score: 15 max: 15 @@ -157,31 +137,29 @@ review: score: 5 max: 5 passed: true - comment: Correct audio waveform plot using filled XY area chart showing positive - and negative amplitude symmetric around zero. + comment: Correct filled area waveform, symmetric above and below zero, time + domain. - id: SC-02 name: Required Features score: 4 max: 4 passed: true - comment: Filled area with semi-transparent opacity, zero reference line, time - X-axis, amplitude Y-axis range (-1 to +1), decay envelope (upper+lower), - peak transient marker, synthetic audio data. + comment: Filled area, zero-line, semi-transparent fill, envelope, x-axis in + seconds, y-axis -1 to 1. - id: SC-03 name: Data Mapping score: 3 max: 3 passed: true - comment: Time on X-axis in seconds, normalized amplitude on Y-axis, all data - visible. + comment: 'X: time in seconds 0.0-0.15, Y: normalized amplitude -1.0 to 1.0. + ~6600 samples (within 5000-50000 spec range).' - id: SC-04 name: Title & Legend score: 3 max: 3 passed: true - comment: Title 'waveform-audio · python · pygal · anyplot.ai' matches required - format exactly. Legend shows Waveform, Decay envelope, Peak transient with - correct color swatches. + comment: Title exactly 'waveform-audio · python · pygal · anyplot.ai'. Legend + labels clear and descriptive. data_quality: score: 15 max: 15 @@ -191,24 +169,22 @@ review: score: 6 max: 6 passed: true - comment: Shows waveform oscillation with attack and decay dynamics, envelope - bounds, peak transient identification, and zero reference baseline — comprehensive - coverage of audio waveform features. + comment: Oscillatory shape, attack-decay dynamics, harmonics, dynamic range, + peak transient, envelope bounds, zero baseline. - id: DQ-02 name: Realistic Context score: 5 max: 5 passed: true - comment: A3 musical note (220 Hz fundamental) with harmonics (2nd, 3rd, 5th) - and physically accurate exponential decay. Neutral topic (music/acoustics). - Scientifically plausible audio physics. + comment: A3 musical note (220 Hz) with physical harmonics and exponential + decay. Standard 44100 Hz sample rate. - id: DQ-03 name: Appropriate Scale score: 4 max: 4 passed: true - comment: 44100 Hz sample rate (CD quality), 0.15 second duration (short clip), - normalized amplitude -1 to +1. All values correct for audio domain. + comment: 'Y: -1.0 to +1.0 normalized. Amplitude peaks at 0.92 — realistic + headroom. 0.15s shows attack-sustain-decay pattern.' code_quality: score: 10 max: 10 @@ -218,60 +194,58 @@ review: score: 3 max: 3 passed: true - comment: 'Flat script: importlib workaround → data generation → chart configuration - → save. No functions or classes beyond necessary workaround.' + comment: No functions or classes. Flat linear structure. - id: CQ-02 name: Reproducibility score: 2 max: 2 passed: true - comment: np.random.seed(42) set. + comment: np.random.seed(42) set. Signal fully deterministic. - id: CQ-03 name: Clean Imports score: 2 max: 2 passed: true - comment: importlib.util, os, sys, numpy, pygal, Style — all used. + comment: All imported modules used. - id: CQ-04 name: Code Elegance score: 2 max: 2 passed: true - comment: Clean, no fake UI elements. The importlib workaround is necessary - and explained. + comment: Per-point dict format with value/label is correct pygal pattern. + Import shadowing workaround is necessary and commented. - id: CQ-05 name: Output & API score: 1 max: 1 passed: true - comment: Saves plot-{THEME}.png and plot-{THEME}.html correctly. + comment: Saves plot-{THEME}.png and plot-{THEME}.html. Uses current pygal + 3.1.0 API. library_mastery: - score: 9 + score: 7 max: 10 items: - id: LM-01 name: Idiomatic Usage - score: 5 + score: 4 max: 5 passed: true - comment: 'Highly idiomatic: Style object, per-point dict format, stroke_style - per series, x_value_formatter, value_formatter, explicit_size, legend_at_bottom, - cubic interpolation, js=[] for PNG mode.' + comment: Per-point dict format with value/label tuples, stroke_style dict, + fill=True, interpolate=cubic, legend_at_bottom, explicit_size — all idiomatic + pygal. - id: LM-02 name: Distinctive Features - score: 4 + score: 3 max: 5 passed: true - comment: 'Per-point dict format {value: (...), label: ''...''} is pygal-distinctive, - enabling rich interactive tooltips in the HTML output. HTML alongside PNG - makes full use of pygal''s interactive SVG nature. Cubic interpolation and - series-level stroke_style customization also showcase pygal capabilities.' - verdict: REJECTED + comment: Rich per-point interactive tooltips across 1200 data points (distinctive + pygal feature). Interactive HTML output. Custom stroke dasharray/linecap. + verdict: APPROVED impl_tags: dependencies: [] techniques: - - html-export - hover-tooltips + - html-export patterns: - data-generation dataprep: