Skip to content

feat(altair): implement line-win-probability#5093

Merged
github-actions[bot] merged 6 commits intomainfrom
implementation/line-win-probability/altair
Mar 20, 2026
Merged

feat(altair): implement line-win-probability#5093
github-actions[bot] merged 6 commits intomainfrom
implementation/line-win-probability/altair

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

Implementation: line-win-probability - altair

Implements the altair version of line-win-probability.

File: plots/line-win-probability/implementations/altair.py

Parent Issue: #4418


🤖 impl-generate workflow

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Mar 20, 2026

AI Review - Attempt 1/3

Image Description

The plot shows a win probability chart for an Eagles vs Cowboys NFL game. The x-axis displays "Game Time (minutes)" from 0 to 60, the y-axis shows "Win Probability (%)" from 0 to 100. A blue line (#306998) traces the probability using monotone interpolation. The area above 50% is filled with a muted teal (#004C54, Eagles) and below 50% with brownish-red (#7B2D26, Cowboys). A dashed gray horizontal line marks the 50% baseline. Red circle markers with white stroke highlight 10 scoring events, each labeled with bold text (e.g., "FG Cowboys 0-3", "TD Eagles 7-3"). Quarter markers (Kickoff, Q2, Q3, Q4, Final) appear at the top with dashed vertical rules at Q2/Q3/Q4. The title reads "Eagles vs Cowboys · line-win-probability · altair · pyplots.ai" with subtitle "Final Score: Eagles 27 - Cowboys 20". The line ends at 100% showing Eagles won.

Score: 85/100

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

Visual Quality (25/30)

  • VQ-01: Text Legibility (7/8) - Title 28pt, subtitle 20pt, axis titles 22pt, ticks 18pt all explicitly set and readable. Event labels at 13pt are slightly small but still legible. Quarter labels at 16pt are good.
  • VQ-02: No Overlap (4/6) - Some event labels are crowded: "TD Eagles 7-3" sits very close to the 50% baseline dashes, and labels around minutes 37-42 ("TD Cowboys 17-17", "FG Cowboys 17-20") are packed tightly. Most are readable but not cleanly separated.
  • VQ-03: Element Visibility (5/6) - Line is clearly visible at strokeWidth=3, area fills at 0.4 opacity work well, event circles at size=200 are prominent. Line could be slightly thicker for the chart size.
  • VQ-04: Color Accessibility (3/4) - Teal vs brownish-red is distinguishable for most colorblind types. However, the red (#E84855) event markers against the brownish-red (#7B2D26) fill area could cause confusion for some viewers.
  • VQ-05: Layout & Canvas (4/4) - Chart fills canvas well at 1600×900 with scale_factor=3. No cut-off, balanced margins.
  • VQ-06: Axis Labels & Title (2/2) - "Game Time (minutes)" and "Win Probability (%)" are descriptive with units.

Design Excellence (13/20)

  • DE-01: Aesthetic Sophistication (5/8) - Team-themed color palette (teal Eagles, maroon Cowboys) is a thoughtful choice. Subtitle with final score adds context. Clean appearance above defaults but not quite publication-level — the Python Blue main line doesn't match either team color, creating slight visual incoherence.
  • DE-02: Visual Refinement (4/6) - Grid disabled via configure_axis, view stroke removed, domain color softened to #cccccc. Dashed baseline and quarter rules are subtle. Good refinement overall.
  • DE-03: Data Storytelling (4/6) - The chart tells a clear game narrative: early Cowboys lead, Eagles fight back, dramatic Q4 swing. Event annotations guide the viewer through key moments. Quarter markers provide temporal structure. Visual hierarchy is effective with colored areas showing momentum.

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) - Correct win probability line chart with area fills above/below 50%.
  • SC-02: Required Features (4/4) - All spec features present: 50% reference line, area fills with team colors, event annotations, final score display, quarter markers.
  • SC-03: Data Mapping (3/3) - X = game time (minutes), Y = win probability (%). Correct mapping with full 0-60 and 0-100 ranges.
  • SC-04: Title & Legend (3/3) - Title includes "line-win-probability · altair · pyplots.ai" in correct format. No legend needed for single-line chart with color-coded areas and annotations.

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) - Shows lead changes, momentum swings, various scoring types (TDs, FGs, INT), close game through Q3 then decisive Q4 pullaway. Probability reaches both extremes (near 30% and up to 100%).
  • DQ-02: Realistic Context (5/5) - NFL game between Eagles and Cowboys with realistic scoring sequence and game flow. Neutral sports context.
  • DQ-03: Appropriate Scale (4/4) - Win probability 0-100%, 60-minute game, realistic probability shifts per scoring event.

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3) - Clean imports → data generation → plot layers → compose → save structure. No functions or classes.
  • CQ-02: Reproducibility (2/2) - np.random.seed(42) set for reproducible noise.
  • CQ-03: Clean Imports (2/2) - All three imports (altair, numpy, pandas) are used.
  • CQ-04: Code Elegance (2/2) - Clean, well-structured. Data generation is necessarily involved but readable. Layer composition is idiomatic Altair.
  • CQ-05: Output & API (1/1) - Saves as plot.png with scale_factor=3.0 and plot.html. Current API.

Library Mastery (7/10)

  • LM-01: Idiomatic Usage (4/5) - Good declarative layer composition with + operator, proper encoding types (:Q, :N), alt.datum for constants, alt.Title with subtitle, configure_axis/configure_view. Could use selection parameters for more idiomatic interactivity.
  • LM-02: Distinctive Features (3/5) - Uses Altair-distinctive features: tooltips for interactive HTML version, layer composition with +, alt.datum for reference values, HTML export. These leverage Altair's declarative grammar well but don't push into advanced territory (selections, conditions, calculated transforms).

Score Caps Applied

  • None

Strengths

  • Excellent spec compliance — all required features (50% baseline, team-colored area fills, event annotations, quarter markers, final score) are present and well-implemented
  • Strong data storytelling with realistic NFL game flow showing lead changes and momentum shifts
  • Clean, idiomatic Altair code with proper layer composition and encoding types
  • Good visual refinement with disabled grid, subtle reference lines, and clean canvas

Weaknesses

  • Event label overlap in crowded areas (minutes 12-18 and 37-42) reduces readability
  • The main line color (#306998 Python Blue) doesn't match either team color, creating visual incoherence with the team-themed area fills
  • Red event markers (#E84855) could be confused with the Cowboys' brownish-red (#7B2D26) fill by colorblind viewers
  • Event label font size (13pt) is slightly small relative to the chart's scale

Issues Found

  1. VQ-02 MODERATE: Event labels overlap in dense scoring regions
    • Fix: Stagger label positions (alternate dy above/below), reduce label count, or offset crowded labels
  2. VQ-04 MINOR: Red event markers too close to Cowboys fill color
    • Fix: Use a neutral marker color (white with dark stroke, or dark gray) that contrasts with both team fills
  3. DE-01 MODERATE: Main line color creates incoherence with team-themed design
  4. VQ-01 MINOR: Event labels at 13pt are small
    • Fix: Increase event label font to at least 14-15pt

AI Feedback for Next Attempt

Fix label overlap in crowded scoring regions by staggering dy offsets (alternate above/below the data point) or using smarter positioning. Change the main line color to a neutral dark tone (charcoal) to avoid clashing with team-colored area fills. Use neutral-colored event markers (white fill with dark stroke) to improve colorblind accessibility. Bump event label font size to 14-15pt for better legibility.

Verdict: REJECTED

@github-actions github-actions Bot added quality:85 Quality score 85/100 ai-rejected Quality not OK, triggers update labels Mar 20, 2026
@github-actions github-actions Bot added ai-attempt-1 First repair attempt and removed ai-rejected Quality not OK, triggers update labels Mar 20, 2026
@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 20, 2026

AI Review - Attempt 2/3

Image Description

The plot displays a win probability chart for an Eagles vs Cowboys NFL game. The x-axis shows "Game Time (minutes)" from 0 to 60, and the y-axis shows "Win Probability (%)" from 0 to 100. A dashed horizontal reference line sits at 50%. The area above 50% is filled with a muted teal (#004C54, Eagles) and below 50% with a muted brownish-red (#7B2D26, Cowboys). A dark charcoal line traces the probability over time. Gold/amber circle markers with dark outlines highlight 10 scoring events, each labeled in bold text (e.g., "FG Cowboys 0-3", "TD Eagles 7-3"). Dashed vertical lines mark quarter boundaries labeled "Kickoff", "Q2", "Q3", "Q4", "Final" at the top. The title reads "Eagles vs Cowboys · line-win-probability · altair · pyplots.ai" with subtitle "Final Score: Eagles 27 - Cowboys 20". The chart tells a story of a back-and-forth game with the Eagles ultimately pulling away in the 4th quarter.

Score: 91/100

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

Visual Quality (28/30)

  • VQ-01: Text Legibility (7/8) - All font sizes explicitly set (title 28pt, subtitle 20pt, axes 22pt/18pt, event labels 15pt, quarter labels 16pt). Event annotation labels at 15pt are slightly on the smaller side but still readable.
  • VQ-02: No Overlap (5/6) - Manual label nudges prevent most overlap effectively. However, "TD Eagles 24-20" is positioned quite far below its data point (near y≈10), creating visual disconnect. Minor crowding in the right portion of the chart.
  • VQ-03: Element Visibility (6/6) - Line at 3.5px strokeWidth is clearly visible, area fills at 0.4 opacity allow the line to stand out, event markers at size 220 with stroke are prominent.
  • VQ-04: Color Accessibility (4/4) - Teal vs brownish-red is colorblind-distinguishable (not a red-green pair). Gold markers provide strong contrast against both fills. Dark charcoal line visible against all backgrounds.
  • VQ-05: Layout & Canvas (4/4) - 1600×900 canvas well-utilized, plot fills the space with balanced margins, no content cut off.
  • VQ-06: Axis Labels & Title (2/2) - "Game Time (minutes)" and "Win Probability (%)" — descriptive with units.

Design Excellence (15/20)

  • DE-01: Aesthetic Sophistication (6/8) - Strong design with intentional team color palette (teal + muted red), gold event markers for contrast, dark charcoal line harmonizing with fills. Custom subtitle with final score. Clearly above defaults but not quite FiveThirtyEight-level polish.
  • DE-02: Visual Refinement (4/6) - Grid disabled, view stroke removed, domain color lightened to #cccccc, dashed baseline and quarter lines are subtle. Good but not every detail polished (e.g., no custom tick formatting).
  • DE-03: Data Storytelling (5/6) - Excellent narrative: annotated scoring events, quarter markers, and subtitle with final score guide the viewer through the game's progression. The momentum swings are immediately visible. Clear focal point at the 4th quarter comeback.

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) - Correct win probability line chart with area fills above/below 50%.
  • SC-02: Required Features (4/4) - All spec features present: 50% reference line ✓, team-colored area fills ✓, scoring event annotations ✓, final score display ✓, quarter markers ✓.
  • SC-03: Data Mapping (3/3) - X=game time (minutes), Y=win probability (0-100%), full range visible.
  • SC-04: Title & Legend (3/3) - Title contains "line-win-probability · altair · pyplots.ai" with game context. No legend needed — team colors are contextually clear from annotations.

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) - Shows momentum swings in both directions, multiple scoring event types (TD, FG, INT), lead changes, a close mid-game period, and a decisive ending. Covers all aspects of a win probability chart.
  • DQ-02: Realistic Context (5/5) - NFL game (Eagles vs Cowboys) with realistic scoring progression. Sports context is neutral and universally relatable.
  • DQ-03: Appropriate Scale (4/4) - Win probability values realistic (0-100%), game duration 60 minutes matches NFL, scores progress realistically through the game.

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3) - Linear flow: imports → data generation → plot layers → composition → save. No functions or classes.
  • CQ-02: Reproducibility (2/2) - np.random.seed(42) set.
  • CQ-03: Clean Imports (2/2) - Only altair, numpy, pandas — all used.
  • CQ-04: Code Elegance (2/2) - Clean, well-organized code. Interactive crosshair elements are native Altair features (not fake — they work in the HTML export). Appropriate complexity for the visualization.
  • CQ-05: Output & API (1/1) - Saves as plot.png and plot.html, uses current Altair API.

Library Mastery (8/10)

  • LM-01: Idiomatic Usage (5/5) - Expert use of Altair's declarative grammar: layered composition with +, encoding types (Q, N), alt.datum for reference values, alt.Title with subtitle, configure_axis and configure_view.
  • LM-02: Distinctive Features (3/5) - Uses selection_point with nearest=True for interactive crosshair, alt.condition for conditional encoding, and voronoi-based hover detection — distinctively Altair patterns. However, these interactive features are only visible in HTML output, not in the reviewed PNG.

Score Caps Applied

  • None

Strengths

  • Excellent spec compliance — all required features implemented with attention to detail
  • Strong data storytelling with annotated scoring events and game narrative
  • Thoughtful team color palette that avoids accessibility issues
  • Good use of Altair's interactive features (selection, conditional encoding) for HTML output
  • Manual label positioning shows care in avoiding text collisions

Weaknesses

  • "TD Eagles 24-20" label positioned far from its data point, creating visual disconnect
  • Event annotation font size (15pt) could be slightly larger for better readability at full resolution

Issues Found

  1. VQ-02 MINOR: "TD Eagles 24-20" label nudged too far from its data point — appears near y≈10 while the event is around y≈55
    • Fix: Adjust label_nudges for this specific event to keep it closer to the data point
  2. LM-02 MODERATE: Interactive crosshair features are only visible in HTML, not the reviewed PNG — limits the perceived library mastery in static output
    • Note: This is an inherent trade-off, not necessarily a fix needed

AI Feedback for Next Attempt

Strong implementation that meets the approval threshold. The team color palette, event annotations, and game narrative create an engaging win probability chart. Minor improvement would be adjusting the "TD Eagles 24-20" label position to stay closer to its data point.

Verdict: APPROVED

@github-actions github-actions Bot added quality:91 Quality score 91/100 ai-approved Quality OK, ready for merge labels Mar 20, 2026
@github-actions github-actions Bot merged commit ad67208 into main Mar 20, 2026
3 checks passed
@github-actions github-actions Bot deleted the implementation/line-win-probability/altair branch March 20, 2026 12:47
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 quality:91 Quality score 91/100

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants