Skip to content

feat(pygal): implement linked-views-selection#7695

Merged
MarkusNeusinger merged 6 commits into
mainfrom
implementation/linked-views-selection/pygal
May 24, 2026
Merged

feat(pygal): implement linked-views-selection#7695
MarkusNeusinger merged 6 commits into
mainfrom
implementation/linked-views-selection/pygal

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

Implementation: linked-views-selection - python/pygal

Implements the python/pygal version of linked-views-selection.

File: plots/linked-views-selection/implementations/python/pygal.py

Parent Issue: #3344


🤖 impl-generate workflow

github-actions Bot and others added 2 commits May 24, 2026 07:30
Regen from quality 81. Addressed:
- Font sizes corrected to sub_style values (44/32/26/26) matching pygal library prompt
- Switched from Okabe-Ito to canonical ANYPLOT_PALETTE (#009E73 first series)
- Fixed PIL composite bug (hex color string → RGB tuple), composite is exactly 3200×1800
- View 3 changed from Line to pygal.Box (Tukey box plot) — distinctive pygal feature, LM-02
- Scatter uses stroke=False for true dot-only scatter (no connecting lines)
- Bar chart per-species (serie-0/1/2 = setosa/versicolor/virginica) enables correct JS selection sync
- HTML interaction upgraded: custom species-selector buttons with CSS-class-based highlight across all three SVG charts
- Storytelling improved: scatter shows 2D petal cluster separation; bar confirms 1D petal spread; box reveals sepal length overlap — coherent scientific narrative

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

claude Bot commented May 24, 2026

AI Review - Attempt 1/3

Image Description

Light render (plot-light.png): Warm off-white background (#FAF8F1). Three-panel composite: top-left scatter plot ("Petal Length vs Petal Width"), top-right bar chart ("Mean Petal Length by Species"), and full-width bottom box chart (titled "linked-views-selection · python · pygal · anyplot.ai"). All three views use the first three anyplot palette colors: teal (#009E73) for setosa, purple (#9418DB) for versicolor, red (#B71D27) for virginica. All text is dark-on-light and clearly legible. Sub-chart axis labels and tick labels appear somewhat small (title_font_size=44 vs. recommended 66 for pygal) but are still readable at this resolution. No clipping or overflow. Legibility verdict: PASS — all text readable, though text sizes are below the style guide recommendation.

Dark render (plot-dark.png): Near-black background (#1A1A17). Same three-panel layout with identical structure. All text is light-colored against the dark background — title, axis labels, tick labels, and legend all render in near-white tones. No dark-on-dark failures. Data series colors are identical to the light render (teal, purple, red) — only chrome has flipped (backgrounds, text, grid tones). Legends appear correctly in each sub-chart. Legibility verdict: PASS — no dark-on-dark failures detected.

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

Score: 80/100

Category Score Max
Visual Quality 25 30
Design Excellence 10 20
Spec Compliance 14 15
Data Quality 14 15
Code Quality 10 10
Library Mastery 7 10
Total 80 100

Visual Quality (25/30)

  • VQ-01: Text Legibility (5/8) — Font sizes explicitly set but below recommended (title 44 vs 66, label 32 vs 56, major_label 26 vs 44); text is readable but appears small in the sub-charts of the composite view
  • VQ-02: No Overlap (6/6) — No text or element overlaps anywhere
  • VQ-03: Element Visibility (5/6) — Scatter dots at size=5 are visible for 150 points; could be slightly larger
  • VQ-04: Color Accessibility (2/2) — Anyplot palette is CVD-safe; teal/purple/red are clearly distinguishable
  • VQ-05: Layout & Canvas (3/4) — Good overall composite layout; bar chart has sparse horizontal space (single x-group label); box chart has significant empty space below data (y-axis 0–4 range unused since sepal lengths cluster at 4.3–7.9)
  • VQ-06: Axis Labels & Title (2/2) — All axes include units: "Petal Length (cm)", "Petal Width (cm)", "Sepal Length (cm)"
  • VQ-07: Palette Compliance (2/2) — First series #009E73 correct; multi-series follows canonical order; backgrounds #FAF8F1/#1A1A17 correct; data colors identical across themes

Design Excellence (10/20)

  • DE-01: Aesthetic Sophistication (4/8) — Custom Style object with anyplot palette and appropriate font sizes for sub-charts; looks like a thoughtfully configured library output rather than a generic default, but falls short of publication-ready
  • DE-02: Visual Refinement (3/6) — INK_MUTED grid colors are a good touch; grid lines are dashed (style guide prefers solid at low opacity); spines not explicitly removed (pygal defaults keep all spines); whitespace is reasonable
  • DE-03: Data Storytelling (3/6) — The three complementary views (scatter for 2D separation, bar for mean comparison, box for distribution) tell a coherent story about Iris species separation; above default but no focal point or visual hierarchy guides the viewer to the key insight

Spec Compliance (14/15)

  • SC-01: Plot Type (5/5) — Three coordinated views: XY scatter, Bar, Box — all correct and distinct chart types
  • SC-02: Required Features (3/4) — Selection mechanism present (species buttons + reset); unselected series fades to opacity 0.08; selection count shown; consistent color encoding across views. Partial deduction: selection is triggered via external species buttons rather than brushing or clicking within a chart view, which is the core "selection in any view" pattern the spec requires
  • SC-03: Data Mapping (3/3) — x=Petal Length, y=Petal Width in scatter; mean Petal Length in bar; Sepal Length distribution in box — all spec data dimensions used correctly
  • SC-04: Title & Legend (3/3) — Title "linked-views-selection · python · pygal · anyplot.ai" present in box chart; legends correctly label setosa/versicolor/virginica in all sub-charts

Data Quality (14/15)

  • DQ-01: Feature Coverage (5/6) — Three chart types showing 2D scatter clustering, mean comparison, and distribution overlap; covers most aspects of linked multi-view visualization; the dynamic selection sync is only visible in HTML, not the static PNG
  • DQ-02: Realistic Context (5/5) — Iris dataset is a canonical real scientific dataset (botany), completely neutral and comprehensible
  • DQ-03: Appropriate Scale (4/4) — Iris sepal/petal measurements are factually correct (petal lengths 1–7cm, widths 0–2.5cm, sepal lengths 4–8cm)

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3) — Flat top-level flow: sys.path fix → tokens → data → 3 charts → composite PNG → HTML. No functions or classes
  • CQ-02: Reproducibility (2/2) — Iris dataset is deterministic; no random data generation
  • CQ-03: Clean Imports (2/2) — All imports are used: os, sys, pandas, pygal, PIL.Image, pygal.style.Style, sklearn.datasets.load_iris
  • CQ-04: Code Elegance (2/2) — The HTML string building is verbose but necessary for embedding multi-SVG interactive views; no over-engineering or fake functionality
  • CQ-05: Output & API (1/1) — Saves plot-{THEME}.png and plot-{THEME}.html; no deprecated API

Library Mastery (7/10)

  • LM-01: Idiomatic Usage (4/5) — Correct use of Style object for theme tokens; correct XY data format (list of tuples); chart.render() for SVG bytes and render_to_png() for intermediate PNGs
  • LM-02: Distinctive Features (3/5) — Creatively exploits pygal's SVG-based architecture: uses chart.render() to capture raw SVG bytes, embeds them in HTML, and leverages pygal's auto-generated .serie-N CSS classes for JavaScript-driven cross-chart selection sync — a use pattern unique to pygal's SVG rendering model

Score Caps Applied

  • None

Strengths

  • Excellent use of the Iris dataset — a real, factually correct, neutral scientific dataset that clearly demonstrates multi-view linked selection
  • Creative SVG export pattern: capturing raw SVG bytes and exploiting pygal's .serie-N CSS classes for cross-chart dimming is a genuinely distinctive pygal technique
  • Perfect palette compliance in both themes — first series is #009E73, canonical order maintained, backgrounds correct, identical data colors across light/dark
  • Complete interactive HTML with species filter buttons, reset, and selection count display
  • Clean KISS code structure with no functions or classes; all 10 code quality points earned

Weaknesses

  • Sub-chart font sizes (title=44, label=32, major_label=26) are below the pygal style-guide recommendation (66/56/44); raise to at least title=54, label=44, major_label=36 in sub-charts so text is more prominent in the composite view
  • Linked selection is via external species buttons, not within-chart brushing or clicking — the spec explicitly says "selection in any view should highlight corresponding points in all other views"; consider making species legend items or chart elements clickable to initiate selection from within a view
  • Box chart y-axis starts at 0 but sepal lengths start at ~4.3; reduce y_range_min to ~3.5 or use pygal range config so data occupies at least 70% of the chart area vertically
  • Design excellence needs more visual hierarchy: de-emphasize gridlines further — consider disabling grid on bar and box charts where they add clutter, and keep grid only on the scatter chart where it aids readability

Issues Found

  1. VQ-01 LOW: Sub-chart font sizes below recommendation — title_font_size=44 vs. recommended 66 for pygal at 3200×1800; even accounting for sub-canvas rendering, the text appears small in the composite final image
    • Fix: Increase to title_font_size=54–58, label_font_size=42–46, major_label_font_size=34–38 for sub-charts
  2. SC-02 PARTIAL: Selection is external-button-only — spec requires selection FROM within a view to propagate to others
    • Fix: Make the pygal legend items or series elements clickable by injecting JavaScript onClick handlers into the embedded SVGs; clicking a series in any chart's legend should sync the active selection across all three charts
  3. VQ-05 MINOR: Box chart has large empty space below data (y-axis 0 to 4.3 unused)
    • Fix: Set y_range_min to approximately 3.5 on the box chart so data fills the plot area
  4. DE-02 LOW: Dashed grid lines present on all charts; style guide prefers no grid or solid thin lines at low opacity
    • Fix: Disable grid on bar and box charts (show_x_guides=False, show_y_guides=False); scatter may keep both-axis grids

AI Feedback for Next Attempt

Increase sub-chart font sizes closer to guide recommendations (title ~54–58, label ~42–46, major_label ~34–38). Make selection initiatable from within chart views: add onClick JavaScript to SVG series elements so clicking a series in any chart updates the active selection for all charts. Fix box chart y-axis range to start at ~3.5 to eliminate the large empty lower area. Disable grid on bar and box charts to reduce visual noise. These changes will improve VQ-01, SC-02, VQ-05, and DE-02 scores significantly.

Verdict: REJECTED

@github-actions github-actions Bot added quality:80 Quality score 80/100 ai-rejected Quality not OK, triggers update labels May 24, 2026
@github-actions github-actions Bot added ai-attempt-1 First repair attempt and removed ai-rejected Quality not OK, triggers update labels May 24, 2026
@github-actions
Copy link
Copy Markdown
Contributor Author

🔧 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 May 24, 2026

AI Review - Attempt 2/3

Image Description

Light render (plot-light.png): Three sub-charts composited on a warm off-white #FAF8F1 background: (1) scatter plot "Petal Length vs Petal Width" (top-left) showing three species clusters — setosa in green #009E73 tightly grouped at low petal values, versicolor in purple #9418DB in the mid-range, virginica in red #B71D27 in the upper-right; (2) bar chart "Mean Petal Length by Species" (top-right) with three bars showing correct heights (setosa ~1.4cm, versicolor ~4.2cm, virginica ~5.6cm); (3) box plot occupying the full bottom row with the anyplot title, y-axis "Sepal Length (cm)" ranging 4–8, Tukey whiskers visible with one outlier for virginica. Sub-chart titles, axis labels (all with units), and tick labels are all readable in dark ink against the light background. No light-on-light failures. Legibility verdict: PASS.

Dark render (plot-dark.png): Identical layout on a warm near-black #1A1A17 background. All data colors are identical to the light render — setosa=green, versicolor=purple, virginica=red — confirming only the chrome flipped. Sub-chart titles, axis labels, and tick labels all render in light/cream text against the dark surface; no dark-on-dark failures observed. The anyplot title in the box plot is legible. Legibility verdict: PASS.

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

Score: 85/100

Category Score Max
Visual Quality 27 30
Design Excellence 11 20
Spec Compliance 15 15
Data Quality 15 15
Code Quality 10 10
Library Mastery 7 10
Total 85 100

Visual Quality (27/30)

  • VQ-01: Text Legibility (7/8) — Font sizes explicitly set (title=54, label=44, major_label=36); readable in both themes. Tick labels slightly below style guide defaults (should be 44 → using 36) making them marginally small in composited sub-charts.
  • VQ-02: No Overlap (6/6) — No overlapping elements in any of the three views
  • VQ-03: Element Visibility (5/6) — Bars and boxes are prominent; scatter dots (dots_size=5) visible but slightly small for 150 points at this scale
  • VQ-04: Color Accessibility (2/2) — anyplot palette is CVD-safe; three species clearly distinguishable
  • VQ-05: Layout & Canvas (3/4) — Multi-chart layout fills canvas well; bar chart's single x-category ("Mean Petal Length") leaves some horizontal axis space underutilized
  • VQ-06: Axis Labels & Title (2/2) — All axis labels include units (cm). Title format correct.
  • VQ-07: Palette Compliance (2/2) — anyplot palette correctly applied; backgrounds #FAF8F1/#1A1A17; theme-adaptive chrome in both renders; data colors identical across themes

Design Excellence (11/20)

  • DE-01: Aesthetic Sophistication (4/8) — Multi-chart layout with consistent theming above defaults; not reaching publication-quality due to standard pygal chart chrome and dotted grid in scatter
  • DE-02: Visual Refinement (3/6) — Selective grid (scatter-only is a good choice), theme-adaptive backgrounds, custom font sizes; pygal doesn't expose spine removal so refinement is limited
  • DE-03: Data Storytelling (4/6) — Intentional chart selection: scatter for clustering (shows clearest separation), bar for magnitude comparison, box for distribution overlap — each view reveals distinct structure; consistent color coding aids cross-view reading

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) — Three coordinated views: scatter (XY), bar (Bar), box plot (Box)
  • SC-02: Required Features (4/4) — Linked selection via HTML/JS (buttons + chart click handlers); reset "Show all" button; unselected opacity=0.08; selection count label; consistent color encoding across all views
  • SC-03: Data Mapping (3/3) — Correct: scatter (PetalLength×PetalWidth+species), bar (species→MeanPetalLength), box (species→SepalLength)
  • SC-04: Title & Legend (3/3) — Title "linked-views-selection · python · pygal · anyplot.ai" correct in box chart. Species legend labels match data.

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) — Three views collectively cover clustering, magnitude differences, distribution overlap, and outliers (Tukey whiskers reveal one virginica outlier)
  • DQ-02: Realistic Context (5/5) — Iris dataset: canonical real-world scientific dataset, neutral and biologically grounded
  • DQ-03: Appropriate Scale (4/4) — Biologically accurate Iris measurements; y-axis 4–8 avoids wasted 0–4 blank space

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3) — Linear structure: imports → data → three sub-charts → composite PNG → HTML. No functions or classes.
  • CQ-02: Reproducibility (2/2) — Iris dataset from sklearn is fully deterministic
  • CQ-03: Clean Imports (2/2) — All imports (os, sys, pandas, pygal, PIL, Style, load_iris) are used
  • CQ-04: Code Elegance (2/2) — Well-structured; HTML string concatenation is verbose but appropriate for complex multi-chart interactive output. No fake functionality.
  • CQ-05: Output & API (1/1) — Saves plot-{THEME}.png and plot-{THEME}.html correctly using current pygal API

Library Mastery (7/10)

  • LM-01: Idiomatic Usage (4/5) — Idiomatic pygal: XY for scatter, Box with box_mode="tukey", Bar, Style object for all theme tokens, show_x_guides/show_y_guides for selective grid control, render() for SVG bytes
  • LM-02: Distinctive Features (3/5) — Distinctive: SVG bytes embedded in multi-chart HTML dashboard using pygal's .serie-N CSS class structure for JS-driven linked selection; box_mode="tukey" (pygal-specific); PIL compositing of multiple pygal sub-chart PNGs into single canvas

Score Caps Applied

  • None

Strengths

  • Perfect spec compliance — all linked selection features implemented: filter buttons, chart-click handlers, reset button, selection count, opacity de-emphasis
  • Correct anyplot palette across all three views with full theme adaptation (both renders pass)
  • Excellent data selection: Iris scatter (clearest cluster separation), bar (magnitude), box (sepal overlap) — each view reveals distinct structure
  • Real HTML/JS interactivity leveraging pygal's SVG class naming for cross-chart linked selection
  • box_mode="tukey" and selective grid (scatter-only) show idiomatic library knowledge

Weaknesses

  • Sub-chart major_label_font_size=36 is slightly below the style guide default of 44 for pygal; at the composited scale, tick labels read as somewhat small — increase to 44
  • Bar chart uses a single x-category ("Mean Petal Length") with three grouped bars, leaving horizontal axis space underutilized — separating bars by species x-label would better communicate the comparison
  • Design could be elevated with annotation callouts (e.g. noting "Setosa cleanly separates by petal dimensions") or annotation on the outlier in the box plot

Issues Found

  1. VQ-01 MINOR: major_label_font_size=36 is below recommended 44 — at composite scale tick labels appear marginally small
    • Fix: Increase major_label_font_size to 44 in sub_style
  2. DE-02 MODERATE: Grid appears as dotted lines in scatter — show_x_guides=True produces dotted grid by default in pygal, which is somewhat busy
    • Fix: Consider setting show_x_guides=False and relying on y-guides only, or keeping both but ensuring they are subtle enough
  3. VQ-05 MINOR: Bar chart x-axis only shows "Mean Petal Length" as a single group label for all three bars — could be clearer
    • Fix: Use separate bar groups or alternative x-labeling to make per-species comparison more explicit

AI Feedback for Next Attempt

Score 85/100 is APPROVED at attempt 2 (threshold ≥80). No repair needed. The implementation covers all spec requirements with real interactive linked selection, correct palette, and appropriate multi-view data storytelling. Minor improvements for future iterations: increase major_label_font_size to 44, consider per-species x-labels in bar chart for clarity.

Verdict: APPROVED

@github-actions github-actions Bot added quality:85 Quality score 85/100 ai-approved Quality OK, ready for merge and removed quality:80 Quality score 80/100 labels May 24, 2026
@MarkusNeusinger MarkusNeusinger merged commit b72e242 into main May 24, 2026
3 checks passed
@MarkusNeusinger MarkusNeusinger deleted the implementation/linked-views-selection/pygal branch May 24, 2026 07: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:85 Quality score 85/100

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant