Skip to content

feat(matplotlib): implement line-win-probability#5087

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

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

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

Implementation: line-win-probability - matplotlib

Implements the matplotlib version of line-win-probability.

File: plots/line-win-probability/implementations/matplotlib.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 displays a win probability chart for an Eagles vs Cowboys NFL game. A dark teal line (#004C54) traces win probability from 50% at play 0 to 100% at play 120. The area above the 50% dashed baseline is filled with semi-transparent dark teal (Eagles), and the area below with light gray (#869397, Cowboys). Six scoring events are annotated with labels (FG 3-0, TD 7-3, TD 10-7, TD 14-13, TD 20-14, TD 27-17) connected by thin lines to colored dots on the probability curve. Quarter boundaries are marked with dotted vertical lines, and Q1-Q4 labels sit near the bottom. The title reads "Eagles 27 – Cowboys 20 · line-win-probability · matplotlib · pyplots.ai". A legend in the upper left identifies Eagles (teal) and Cowboys (gray). Top and right spines are removed. The y-axis shows 0%-100% in 25% increments; x-axis shows play number 0-120.

Score: 87/100

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

Visual Quality (29/30)

  • VQ-01: Text Legibility (8/8) - All font sizes explicitly set: title 24pt, labels 20pt, ticks 16pt, annotations 12pt, legend 16pt
  • VQ-02: No Overlap (6/6) - No overlapping text; annotations well-spaced with offset logic
  • VQ-03: Element Visibility (6/6) - Line width 3, markers size 7 with white edge, fills clearly visible
  • VQ-04: Color Accessibility (3/4) - Teal and gray are colorblind-safe (no red-green), but the Cowboys gray (#869397) at alpha=0.3 is quite faint and could have stronger contrast against the background
  • VQ-05: Layout & Canvas (4/4) - 16:9 aspect ratio, tight_layout, plot fills canvas well with balanced margins
  • VQ-06: Axis Labels & Title (2/2) - "Play Number" and "Win Probability" are descriptive; y-axis shows percentage units

Design Excellence (13/20)

  • DE-01: Aesthetic Sophistication (5/8) - Thoughtful team-specific color scheme (Eagles teal, Cowboys silver-gray), clean typography with medium fontweight, subtle quarter dividers — clearly above defaults but not FiveThirtyEight-level polish
  • DE-02: Visual Refinement (4/6) - Top/right spines removed, no distracting grid, subtle dotted quarter dividers at low alpha, generous whitespace — good refinement but could push further with y-axis gridlines
  • DE-03: Data Storytelling (4/6) - Fill colors convey momentum shifts at a glance, annotations mark key scoring events, the dramatic convergence to 100% at game end creates a clear narrative arc — good visual hierarchy

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) - Correct win probability line chart with filled areas
  • SC-02: Required Features (4/4) - Y-axis 0-100% ✓, 50% reference line ✓, fill above/below with team colors ✓, scoring event annotations ✓, final score in title ✓, quarter markers ✓
  • SC-03: Data Mapping (3/3) - X = play number, Y = win probability, all data visible within axes
  • SC-04: Title & Legend (3/3) - Title includes final score + spec-id + library + pyplots.ai; legend correctly identifies both teams

Data Quality (14/15)

  • DQ-01: Feature Coverage (5/6) - Shows momentum swings in both directions, lead changes, scoring events from both teams, and final convergence — could benefit from a more dramatic lead change to showcase the full range
  • DQ-02: Realistic Context (5/5) - Real NFL teams (Eagles vs Cowboys), realistic scoring progression, neutral sports topic
  • DQ-03: Appropriate Scale (4/4) - Win probability stays in [0.02, 1.0], scoring shifts are realistic magnitudes, play count matches NFL game length

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3) - Clean linear flow: imports → data generation → plotting → styling → save
  • CQ-02: Reproducibility (2/2) - np.random.seed(42) set at top
  • CQ-03: Clean Imports (2/2) - All three imports used (matplotlib.patches, pyplot, numpy)
  • CQ-04: Code Elegance (2/2) - Appropriate complexity, clean event-driven data generation, no fake functionality
  • CQ-05: Output & API (1/1) - Saves as plot.png with dpi=300, no deprecated API usage

Library Mastery (6/10)

  • LM-01: Idiomatic Usage (4/5) - Good use of Axes methods throughout, fill_between with where+interpolate, annotate with arrowprops, axhline/axvline, mpatches for custom legend
  • LM-02: Distinctive Features (2/5) - fill_between with conditional where parameter is somewhat distinctive to matplotlib, but overall the implementation doesn't showcase deeply unique matplotlib capabilities (e.g., custom transforms, PathEffects, FuncFormatter)

Score Caps Applied

  • None — no caps triggered

Strengths

  • Perfect spec compliance: every requirement from the specification is implemented
  • Excellent data storytelling with annotations, team-colored fills, and quarter markers creating a clear game narrative
  • Clean, well-structured code with appropriate complexity
  • All font sizes explicitly set following library guidelines exactly

Weaknesses

  • Cowboys fill color is too faint — the gray at alpha=0.3 lacks visual weight compared to the Eagles teal
  • Could leverage more distinctive matplotlib features (PathEffects for text glow, FuncFormatter for custom tick formatting, subtle y-axis gridlines)
  • The line color stays Eagles green throughout — changing color when below 50% would reinforce the momentum story

Issues Found

  1. VQ-04 MINOR: Cowboys fill (#869397 at alpha=0.3) is very faint against white background, reducing visual impact of away-team momentum
  2. LM-02 LOW: Generic matplotlib usage without showcasing distinctive features
    • Fix: Add PathEffects for text shadow on annotations, use FuncFormatter for y-axis, add subtle y-axis gridlines
  3. DE-01 MODERATE: Design is good but not publication-quality
    • Fix: Add subtle y-axis gridlines (alpha=0.15), use a slightly warmer background tint, consider gradient fill or line color that changes based on which team leads

AI Feedback for Next Attempt

Boost Cowboys fill visibility with a more saturated color or higher alpha. Add subtle y-axis gridlines (alpha=0.15) for easier probability reading. Leverage distinctive matplotlib features: PathEffects for annotation text, FuncFormatter for y-axis percentage formatting. Consider making the line color change based on which team is leading (teal above 50%, Cowboys color below) to strengthen the momentum narrative. These changes would push Design Excellence and Library Mastery scores higher.

Verdict: REJECTED

@github-actions github-actions Bot added quality:87 Quality score 87/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 NFL game between the Eagles and Cowboys. The x-axis shows "Play Number" (0–120) and the y-axis shows "Win Probability" (0%–100%). A dashed horizontal line marks the 50% baseline. The area above 50% is filled with a muted teal-green (Eagles, #004C54) and below 50% with navy blue (Cowboys, #3594). The main probability line changes color based on which team leads. Six key scoring events are annotated with bold labels (FG 3-0, TD 7-3, TD 10-7, TD 14-13, TD 20-14, TD 27-17) connected by thin lines to small dots on the curve, each with a white stroke for readability. Quarter boundaries (Q1–Q4) are shown as dotted vertical lines with labels at the bottom. The title reads "Eagles 27 – Cowboys 20 · line-win-probability · matplotlib · pyplots.ai". A legend in the upper left identifies the team color fills. The probability converges sharply to 100% at game end. Top and right spines are removed; a subtle y-axis grid aids reading.

Score: 92/100

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

Visual Quality (29/30)

  • VQ-01: Text Legibility (8/8) - All font sizes explicitly set: title 24pt, axis labels 20pt, ticks 16pt, annotations 12pt bold, quarter labels 16pt
  • VQ-02: No Overlap (6/6) - All annotations well-spaced with white path effects ensuring readability over fill areas
  • VQ-03: Element Visibility (5/6) - Line width 3 is clear, markers at scoring events visible with white edge; fill areas thin in narrow Cowboys-lead regions
  • VQ-04: Color Accessibility (4/4) - Teal green vs navy blue fully distinguishable for all color vision types
  • VQ-05: Layout & Canvas (4/4) - 16:9 figure with tight_layout, plot fills canvas well with balanced margins
  • VQ-06: Axis Labels & Title (2/2) - "Play Number" and "Win Probability" are descriptive; percentage formatting on y-axis

Design Excellence (16/20)

  • DE-01: Aesthetic Sophistication (6/8) - Team-specific color palette, color-changing line, intentional fill alpha differentiation (0.3 vs 0.45), path effects on annotations — clearly above defaults, approaching broadcast-quality
  • DE-02: Visual Refinement (5/6) - Top/right spines removed, subtle y-axis grid (alpha=0.15), dotted quarter dividers (alpha=0.4), generous whitespace, white stroke on annotation text
  • DE-03: Data Storytelling (5/6) - Clear game narrative through color fills showing momentum, annotated scoring events marking turning points, convergence to final outcome — viewer immediately grasps the game flow

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) - Win probability line chart, correct type
  • SC-02: Required Features (4/4) - Y-axis 0–100% ✓, 50% reference line ✓, team color fills above/below 50% ✓, scoring event annotations ✓, final score in title ✓, quarter markers ✓
  • SC-03: Data Mapping (3/3) - X=play number, Y=win probability, axes show full range
  • SC-04: Title & Legend (3/3) - Title includes final score and follows {spec-id} · {library} · pyplots.ai format; legend correctly identifies team fills

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) - Shows field goals and touchdowns, lead changes, momentum swings, close mid-game periods, and decisive convergence
  • DQ-02: Realistic Context (5/5) - Eagles vs Cowboys NFL game with plausible 27-20 final score; sports context is neutral
  • DQ-03: Appropriate Scale (4/4) - Probability shifts from scoring events are realistic; convergence at game end is natural

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3) - Clean imports → data → plot → save flow with no functions or classes
  • CQ-02: Reproducibility (2/2) - np.random.seed(42) set
  • CQ-03: Clean Imports (2/2) - All imports used: patches, patheffects, pyplot, ticker, numpy
  • CQ-04: Code Elegance (2/2) - Appropriate complexity, no fake UI, clean segment-based line coloring
  • CQ-05: Output & API (1/1) - Saves as plot.png with dpi=300 and bbox_inches='tight'

Library Mastery (7/10)

  • LM-01: Idiomatic Usage (4/5) - Uses ax methods throughout, fill_between with interpolate, FuncFormatter, tight_layout; segment-by-segment line loop works but LineCollection would be more idiomatic
  • LM-02: Distinctive Features (3/5) - fill_between with where/interpolate, patheffects for text stroke, FuncFormatter for percentage formatting, custom legend with mpatches

Score Caps Applied

  • None

Strengths

  • Excellent spec compliance — all required features (50% baseline, team color fills, scoring annotations, quarter markers, final score) are present and well-implemented
  • Strong data storytelling through color fills, annotated scoring events, and natural probability convergence
  • Professional visual polish with path effects, custom team colors, and refined typography
  • Clean, reproducible code with appropriate complexity

Weaknesses

  • Segment-by-segment line plotting loop is less efficient than using matplotlib's LineCollection
  • Fill area visibility is slightly reduced in narrow Cowboys-lead regions due to thin vertical extent

Issues Found

  1. LM-01 MINOR: Line plotted segment-by-segment in a Python loop rather than using LineCollection for color-mapped segments
    • Fix: Use matplotlib.collections.LineCollection for more idiomatic color-varying lines
  2. VQ-03 MINOR: Cowboys fill area barely visible in narrow lead regions around plays 22-35
    • Fix: Could increase Cowboys fill alpha slightly or ensure minimum fill visibility

AI Feedback for Next Attempt

Strong implementation that meets all spec requirements with professional polish. Minor improvements possible in library idiom usage (LineCollection) and fill visibility in thin regions, but overall quality is publication-ready.

Verdict: APPROVED

@github-actions github-actions Bot added quality:92 Quality score 92/100 ai-approved Quality OK, ready for merge labels Mar 20, 2026
@github-actions github-actions Bot merged commit 9777a4e into main Mar 20, 2026
@github-actions github-actions Bot deleted the implementation/line-win-probability/matplotlib branch March 20, 2026 12:44
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:87 Quality score 87/100 quality:92 Quality score 92/100

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants