From b31bbc4bf2659ebf8c7ed38b4680fddcd4875339 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 20 Mar 2026 12:30:41 +0000 Subject: [PATCH 1/5] feat(matplotlib): implement line-win-probability --- .../implementations/matplotlib.py | 143 ++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 plots/line-win-probability/implementations/matplotlib.py diff --git a/plots/line-win-probability/implementations/matplotlib.py b/plots/line-win-probability/implementations/matplotlib.py new file mode 100644 index 0000000000..977424a681 --- /dev/null +++ b/plots/line-win-probability/implementations/matplotlib.py @@ -0,0 +1,143 @@ +"""pyplots.ai +line-win-probability: Win Probability Chart +Library: matplotlib | Python 3.13 +Quality: pending | Created: 2026-03-20 +""" + +import matplotlib.patches as mpatches +import matplotlib.pyplot as plt +import numpy as np + + +# Data - simulated NFL game: Eagles vs Cowboys +np.random.seed(42) + +# Game plays (0 to ~120 plays) +n_plays = 120 +plays = np.arange(n_plays + 1) + +# Build win probability with realistic scoring events +win_prob = np.full(n_plays + 1, 0.50) + +# Scoring events: (play_number, probability_shift, label) +scoring_events = [ + (8, 0.12, "PHI Field Goal (3-0)"), + (22, -0.10, "DAL Touchdown (7-3)"), + (35, 0.15, "PHI Touchdown (10-7)"), + (48, 0.08, "PHI Field Goal (13-7)"), + (58, -0.18, "DAL Touchdown (14-13)"), + (72, 0.14, "PHI Touchdown (20-14)"), + (85, -0.06, "DAL Field Goal (20-17)"), + (95, 0.12, "PHI Touchdown (27-17)"), + (110, -0.05, "DAL Field Goal (27-20)"), +] + +# Generate smooth probability curve with scoring jumps +prob = 0.50 +noise = np.random.normal(0, 0.012, n_plays + 1) +event_indices = {e[0]: (e[1], e[2]) for e in scoring_events} + +for i in range(1, n_plays + 1): + if i in event_indices: + prob += event_indices[i][0] + prob += noise[i] + # Mean reversion toward current level + prob = np.clip(prob, 0.02, 0.98) + win_prob[i] = prob + +# Force convergence to final outcome: Eagles win +for i in range(105, n_plays + 1): + t = (i - 105) / (n_plays - 105) + win_prob[i] = win_prob[105] * (1 - t**2) + 1.0 * t**2 + +# Quarter boundaries (roughly 30 plays each) +quarter_boundaries = [0, 30, 60, 90, n_plays] +quarter_labels = ["Q1", "Q2", "Q3", "Q4"] + +# Colors +eagles_green = "#004C54" +cowboys_blue = "#869397" +baseline_color = "#444444" + +# Plot +fig, ax = plt.subplots(figsize=(16, 9)) + +# Fill above/below 50% +ax.fill_between(plays, win_prob, 0.5, where=(win_prob >= 0.5), color=eagles_green, alpha=0.3, interpolate=True) +ax.fill_between(plays, win_prob, 0.5, where=(win_prob < 0.5), color=cowboys_blue, alpha=0.3, interpolate=True) + +# Win probability line +ax.plot(plays, win_prob, color=eagles_green, linewidth=3, zorder=3) + +# 50% baseline +ax.axhline(y=0.5, color=baseline_color, linewidth=1.5, linestyle="--", alpha=0.5, zorder=2) + +# Quarter dividers +for qb in quarter_boundaries[1:-1]: + ax.axvline(x=qb, color="#999999", linewidth=1, linestyle=":", alpha=0.4) + +# Quarter labels +for i, label in enumerate(quarter_labels): + mid = (quarter_boundaries[i] + quarter_boundaries[i + 1]) / 2 + ax.text(mid, 0.03, label, ha="center", va="center", fontsize=16, color="#888888", fontweight="medium") + +# Annotate key scoring events +annotation_events = [ + (8, "FG 3-0"), + (22, "TD 7-3"), + (35, "TD 10-7"), + (58, "TD 14-13"), + (72, "TD 20-14"), + (95, "TD 27-17"), +] + +for play_idx, label in annotation_events: + wp = win_prob[play_idx] + offset_y = 0.06 if wp >= 0.5 else -0.06 + ax.annotate( + label, + xy=(play_idx, wp), + xytext=(play_idx, wp + offset_y), + fontsize=12, + fontweight="medium", + ha="center", + va="center", + color="#333333", + arrowprops={"arrowstyle": "-", "color": "#999999", "linewidth": 0.8}, + zorder=4, + ) + +# Scatter dots on scoring events for visibility +for play_idx, _ in annotation_events: + ax.plot( + play_idx, + win_prob[play_idx], + "o", + color=eagles_green if win_prob[play_idx] >= 0.5 else cowboys_blue, + markersize=7, + zorder=5, + markeredgecolor="white", + markeredgewidth=1, + ) + +# Style +ax.set_xlim(0, n_plays) +ax.set_ylim(0, 1) +ax.set_yticks([0, 0.25, 0.5, 0.75, 1.0]) +ax.set_yticklabels(["0%", "25%", "50%", "75%", "100%"]) +ax.set_xlabel("Play Number", fontsize=20) +ax.set_ylabel("Win Probability", fontsize=20) +ax.set_title( + "Eagles 27 – Cowboys 20 · line-win-probability · matplotlib · pyplots.ai", fontsize=24, fontweight="medium" +) +ax.tick_params(axis="both", labelsize=16) +ax.spines["top"].set_visible(False) +ax.spines["right"].set_visible(False) + +# Legend +eagles_patch = mpatches.Patch(color=eagles_green, alpha=0.4, label="Eagles") +cowboys_patch = mpatches.Patch(color=cowboys_blue, alpha=0.4, label="Cowboys") +ax.legend(handles=[eagles_patch, cowboys_patch], fontsize=16, loc="upper left", framealpha=0.8, edgecolor="none") + +plt.tight_layout() +plt.savefig("plot.png", dpi=300, bbox_inches="tight") From 0bdc1e52f86159d5e47cad3233aec17f6c18b9e5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 20 Mar 2026 12:30:50 +0000 Subject: [PATCH 2/5] chore(matplotlib): add metadata for line-win-probability --- .../metadata/matplotlib.yaml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 plots/line-win-probability/metadata/matplotlib.yaml diff --git a/plots/line-win-probability/metadata/matplotlib.yaml b/plots/line-win-probability/metadata/matplotlib.yaml new file mode 100644 index 0000000000..5c8c4a2454 --- /dev/null +++ b/plots/line-win-probability/metadata/matplotlib.yaml @@ -0,0 +1,19 @@ +# Per-library metadata for matplotlib implementation of line-win-probability +# Auto-generated by impl-generate.yml + +library: matplotlib +specification_id: line-win-probability +created: '2026-03-20T12:30:49Z' +updated: '2026-03-20T12:30:49Z' +generated_by: claude-opus-4-5-20251101 +workflow_run: 23342814407 +issue: 4418 +python_version: 3.14.3 +library_version: 3.10.8 +preview_url: https://storage.googleapis.com/pyplots-images/plots/line-win-probability/matplotlib/plot.png +preview_thumb: https://storage.googleapis.com/pyplots-images/plots/line-win-probability/matplotlib/plot_thumb.png +preview_html: null +quality_score: null +review: + strengths: [] + weaknesses: [] From 2e6756a949b6f7216b8b18fe23ba41f460b03eb7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 20 Mar 2026 12:34:58 +0000 Subject: [PATCH 3/5] chore(matplotlib): update quality score 87 and review feedback for line-win-probability --- .../implementations/matplotlib.py | 6 +- .../metadata/matplotlib.yaml | 219 +++++++++++++++++- 2 files changed, 215 insertions(+), 10 deletions(-) diff --git a/plots/line-win-probability/implementations/matplotlib.py b/plots/line-win-probability/implementations/matplotlib.py index 977424a681..5456a32540 100644 --- a/plots/line-win-probability/implementations/matplotlib.py +++ b/plots/line-win-probability/implementations/matplotlib.py @@ -1,7 +1,7 @@ -"""pyplots.ai +""" pyplots.ai line-win-probability: Win Probability Chart -Library: matplotlib | Python 3.13 -Quality: pending | Created: 2026-03-20 +Library: matplotlib 3.10.8 | Python 3.14.3 +Quality: 87/100 | Created: 2026-03-20 """ import matplotlib.patches as mpatches diff --git a/plots/line-win-probability/metadata/matplotlib.yaml b/plots/line-win-probability/metadata/matplotlib.yaml index 5c8c4a2454..57bac1014c 100644 --- a/plots/line-win-probability/metadata/matplotlib.yaml +++ b/plots/line-win-probability/metadata/matplotlib.yaml @@ -1,10 +1,7 @@ -# Per-library metadata for matplotlib implementation of line-win-probability -# Auto-generated by impl-generate.yml - library: matplotlib specification_id: line-win-probability created: '2026-03-20T12:30:49Z' -updated: '2026-03-20T12:30:49Z' +updated: '2026-03-20T12:34:58Z' generated_by: claude-opus-4-5-20251101 workflow_run: 23342814407 issue: 4418 @@ -13,7 +10,215 @@ library_version: 3.10.8 preview_url: https://storage.googleapis.com/pyplots-images/plots/line-win-probability/matplotlib/plot.png preview_thumb: https://storage.googleapis.com/pyplots-images/plots/line-win-probability/matplotlib/plot_thumb.png preview_html: null -quality_score: null +quality_score: 87 review: - strengths: [] - weaknesses: [] + 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, FuncFormatter, + subtle y-axis gridlines) + - The line color stays Eagles green throughout — changing color when below 50% would + reinforce the momentum story + 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. + criteria_checklist: + visual_quality: + score: 29 + max: 30 + items: + - id: VQ-01 + name: Text Legibility + score: 8 + max: 8 + passed: true + comment: 'All font sizes explicitly set: title 24pt, labels 20pt, ticks 16pt, + annotations 12pt, legend 16pt' + - id: VQ-02 + name: No Overlap + score: 6 + max: 6 + passed: true + comment: No overlapping text; annotations well-spaced with offset logic + - id: VQ-03 + name: Element Visibility + score: 6 + max: 6 + passed: true + comment: Line width 3, markers size 7 with white edge, fills clearly visible + - id: VQ-04 + name: Color Accessibility + score: 3 + max: 4 + passed: true + comment: Teal and gray are colorblind-safe but Cowboys gray at alpha=0.3 is + quite faint + - id: VQ-05 + name: Layout & Canvas + score: 4 + max: 4 + passed: true + comment: 16:9 aspect ratio, tight_layout, plot fills canvas well + - id: VQ-06 + name: Axis Labels & Title + score: 2 + max: 2 + passed: true + comment: Descriptive labels with percentage units on y-axis + design_excellence: + score: 13 + max: 20 + items: + - id: DE-01 + name: Aesthetic Sophistication + score: 5 + max: 8 + passed: true + comment: Team-specific colors, clean typography, above defaults but not publication-level + - id: DE-02 + name: Visual Refinement + score: 4 + max: 6 + passed: true + comment: Spines removed, subtle quarter dividers, no distracting grid + - id: DE-03 + name: Data Storytelling + score: 4 + max: 6 + passed: true + comment: Fill colors convey momentum, annotations mark key events, dramatic + convergence at end + spec_compliance: + score: 15 + max: 15 + items: + - id: SC-01 + name: Plot Type + score: 5 + max: 5 + passed: true + comment: Correct win probability line chart with filled areas + - id: SC-02 + name: Required Features + score: 4 + max: 4 + passed: true + comment: 'All spec features present: 50% line, fills, annotations, quarter + markers, final score' + - id: SC-03 + name: Data Mapping + score: 3 + max: 3 + passed: true + comment: X = play number, Y = win probability, all data visible + - id: SC-04 + name: Title & Legend + score: 3 + max: 3 + passed: true + comment: Title includes score + spec-id + library + pyplots.ai; legend identifies + both teams + data_quality: + score: 14 + max: 15 + items: + - id: DQ-01 + name: Feature Coverage + score: 5 + max: 6 + passed: true + comment: Shows momentum swings both directions, lead changes, scoring from + both teams + - id: DQ-02 + name: Realistic Context + score: 5 + max: 5 + passed: true + comment: Real NFL teams, realistic scoring progression, neutral sports topic + - id: DQ-03 + name: Appropriate Scale + score: 4 + max: 4 + passed: true + comment: Win probability in realistic range, appropriate scoring shift magnitudes + code_quality: + score: 10 + max: 10 + items: + - id: CQ-01 + name: KISS Structure + score: 3 + max: 3 + passed: true + comment: 'Clean linear flow: imports, data, plot, save' + - id: CQ-02 + name: Reproducibility + score: 2 + max: 2 + passed: true + comment: np.random.seed(42) set at top + - id: CQ-03 + name: Clean Imports + score: 2 + max: 2 + passed: true + comment: All three imports used + - id: CQ-04 + name: Code Elegance + score: 2 + max: 2 + passed: true + comment: Appropriate complexity, no fake functionality + - id: CQ-05 + name: Output & API + score: 1 + max: 1 + passed: true + comment: Saves as plot.png with dpi=300, no deprecated API + library_mastery: + score: 6 + max: 10 + items: + - id: LM-01 + name: Idiomatic Usage + score: 4 + max: 5 + passed: true + comment: Good use of Axes methods, fill_between, annotate with arrowprops, + mpatches + - id: LM-02 + name: Distinctive Features + score: 2 + max: 5 + passed: false + comment: fill_between with where is somewhat distinctive but no PathEffects, + FuncFormatter, or other unique features + verdict: REJECTED +impl_tags: + dependencies: [] + techniques: + - annotations + - custom-legend + - manual-ticks + patterns: + - data-generation + - iteration-over-groups + dataprep: + - cumulative-sum + styling: + - alpha-blending + - edge-highlighting From 0c9c10c4566733c4c65015dce78672e1c28bd39b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 20 Mar 2026 12:38:18 +0000 Subject: [PATCH 4/5] fix(matplotlib): address review feedback for line-win-probability Attempt 1/3 - fixes based on AI review --- .../implementations/matplotlib.py | 31 ++++++++++++------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/plots/line-win-probability/implementations/matplotlib.py b/plots/line-win-probability/implementations/matplotlib.py index 5456a32540..e316585bb3 100644 --- a/plots/line-win-probability/implementations/matplotlib.py +++ b/plots/line-win-probability/implementations/matplotlib.py @@ -1,11 +1,13 @@ -""" pyplots.ai +"""pyplots.ai line-win-probability: Win Probability Chart Library: matplotlib 3.10.8 | Python 3.14.3 Quality: 87/100 | Created: 2026-03-20 """ import matplotlib.patches as mpatches +import matplotlib.patheffects as pe import matplotlib.pyplot as plt +import matplotlib.ticker as mticker import numpy as np @@ -56,7 +58,7 @@ # Colors eagles_green = "#004C54" -cowboys_blue = "#869397" +cowboys_navy = "#003594" baseline_color = "#444444" # Plot @@ -64,10 +66,12 @@ # Fill above/below 50% ax.fill_between(plays, win_prob, 0.5, where=(win_prob >= 0.5), color=eagles_green, alpha=0.3, interpolate=True) -ax.fill_between(plays, win_prob, 0.5, where=(win_prob < 0.5), color=cowboys_blue, alpha=0.3, interpolate=True) +ax.fill_between(plays, win_prob, 0.5, where=(win_prob < 0.5), color=cowboys_navy, alpha=0.45, interpolate=True) -# Win probability line -ax.plot(plays, win_prob, color=eagles_green, linewidth=3, zorder=3) +# Win probability line - color changes based on which team leads +for i in range(len(plays) - 1): + color = eagles_green if win_prob[i] >= 0.5 else cowboys_navy + ax.plot(plays[i : i + 2], win_prob[i : i + 2], color=color, linewidth=3, zorder=3, solid_capstyle="round") # 50% baseline ax.axhline(y=0.5, color=baseline_color, linewidth=1.5, linestyle="--", alpha=0.5, zorder=2) @@ -94,18 +98,19 @@ for play_idx, label in annotation_events: wp = win_prob[play_idx] offset_y = 0.06 if wp >= 0.5 else -0.06 - ax.annotate( + txt = ax.annotate( label, xy=(play_idx, wp), xytext=(play_idx, wp + offset_y), fontsize=12, - fontweight="medium", + fontweight="bold", ha="center", va="center", - color="#333333", + color="#222222", arrowprops={"arrowstyle": "-", "color": "#999999", "linewidth": 0.8}, zorder=4, ) + txt.set_path_effects([pe.withStroke(linewidth=3, foreground="white")]) # Scatter dots on scoring events for visibility for play_idx, _ in annotation_events: @@ -113,7 +118,7 @@ play_idx, win_prob[play_idx], "o", - color=eagles_green if win_prob[play_idx] >= 0.5 else cowboys_blue, + color=eagles_green if win_prob[play_idx] >= 0.5 else cowboys_navy, markersize=7, zorder=5, markeredgecolor="white", @@ -124,7 +129,11 @@ ax.set_xlim(0, n_plays) ax.set_ylim(0, 1) ax.set_yticks([0, 0.25, 0.5, 0.75, 1.0]) -ax.set_yticklabels(["0%", "25%", "50%", "75%", "100%"]) +ax.yaxis.set_major_formatter(mticker.FuncFormatter(lambda x, _: f"{x:.0%}")) + +# Subtle y-axis gridlines for easier probability reading +ax.yaxis.grid(True, alpha=0.15, linewidth=0.8, color="#888888") +ax.set_axisbelow(True) ax.set_xlabel("Play Number", fontsize=20) ax.set_ylabel("Win Probability", fontsize=20) ax.set_title( @@ -136,7 +145,7 @@ # Legend eagles_patch = mpatches.Patch(color=eagles_green, alpha=0.4, label="Eagles") -cowboys_patch = mpatches.Patch(color=cowboys_blue, alpha=0.4, label="Cowboys") +cowboys_patch = mpatches.Patch(color=cowboys_navy, alpha=0.5, label="Cowboys") ax.legend(handles=[eagles_patch, cowboys_patch], fontsize=16, loc="upper left", framealpha=0.8, edgecolor="none") plt.tight_layout() From 9d61c04ca7c58d38fa21a206167867a3f8c0f19f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 20 Mar 2026 12:44:26 +0000 Subject: [PATCH 5/5] chore(matplotlib): update quality score 92 and review feedback for line-win-probability --- .../implementations/matplotlib.py | 4 +- .../metadata/matplotlib.yaml | 131 +++++++++--------- 2 files changed, 67 insertions(+), 68 deletions(-) diff --git a/plots/line-win-probability/implementations/matplotlib.py b/plots/line-win-probability/implementations/matplotlib.py index e316585bb3..d43a1e1648 100644 --- a/plots/line-win-probability/implementations/matplotlib.py +++ b/plots/line-win-probability/implementations/matplotlib.py @@ -1,7 +1,7 @@ -"""pyplots.ai +""" pyplots.ai line-win-probability: Win Probability Chart Library: matplotlib 3.10.8 | Python 3.14.3 -Quality: 87/100 | Created: 2026-03-20 +Quality: 92/100 | Created: 2026-03-20 """ import matplotlib.patches as mpatches diff --git a/plots/line-win-probability/metadata/matplotlib.yaml b/plots/line-win-probability/metadata/matplotlib.yaml index 57bac1014c..eb4972d022 100644 --- a/plots/line-win-probability/metadata/matplotlib.yaml +++ b/plots/line-win-probability/metadata/matplotlib.yaml @@ -1,7 +1,7 @@ library: matplotlib specification_id: line-win-probability created: '2026-03-20T12:30:49Z' -updated: '2026-03-20T12:34:58Z' +updated: '2026-03-20T12:44:26Z' generated_by: claude-opus-4-5-20251101 workflow_run: 23342814407 issue: 4418 @@ -10,32 +10,32 @@ library_version: 3.10.8 preview_url: https://storage.googleapis.com/pyplots-images/plots/line-win-probability/matplotlib/plot.png preview_thumb: https://storage.googleapis.com/pyplots-images/plots/line-win-probability/matplotlib/plot_thumb.png preview_html: null -quality_score: 87 +quality_score: 92 review: 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 + - Excellent spec compliance — all required features (50% baseline, team color fills, + scoring annotations, quarter markers, final score) 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: - - 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, FuncFormatter, - subtle y-axis gridlines) - - The line color stays Eagles green throughout — changing color when below 50% would - reinforce the momentum story - 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. + - Segment-by-segment line plotting loop is less efficient than using LineCollection + - Fill area visibility slightly reduced in narrow Cowboys-lead regions + 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) and below 50% with + navy blue (Cowboys). 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. criteria_checklist: visual_quality: score: 29 @@ -47,61 +47,62 @@ review: max: 8 passed: true comment: 'All font sizes explicitly set: title 24pt, labels 20pt, ticks 16pt, - annotations 12pt, legend 16pt' + annotations 12pt, quarter labels 16pt' - id: VQ-02 name: No Overlap score: 6 max: 6 passed: true - comment: No overlapping text; annotations well-spaced with offset logic + comment: All annotations well-spaced with white path effects ensuring readability - id: VQ-03 name: Element Visibility - score: 6 + score: 5 max: 6 passed: true - comment: Line width 3, markers size 7 with white edge, fills clearly visible + comment: Line and markers clear; fill areas thin in narrow Cowboys-lead regions - id: VQ-04 name: Color Accessibility - score: 3 + score: 4 max: 4 passed: true - comment: Teal and gray are colorblind-safe but Cowboys gray at alpha=0.3 is - quite faint + comment: Teal green vs navy blue fully distinguishable for all color vision + types - id: VQ-05 name: Layout & Canvas score: 4 max: 4 passed: true - comment: 16:9 aspect ratio, tight_layout, plot fills canvas well + comment: 16:9 figure with tight_layout, plot fills canvas well - id: VQ-06 name: Axis Labels & Title score: 2 max: 2 passed: true - comment: Descriptive labels with percentage units on y-axis + comment: Descriptive labels with percentage formatting on y-axis design_excellence: - score: 13 + score: 16 max: 20 items: - id: DE-01 name: Aesthetic Sophistication - score: 5 + score: 6 max: 8 passed: true - comment: Team-specific colors, clean typography, above defaults but not publication-level + comment: Team-specific palette, color-changing line, path effects, approaching + broadcast quality - id: DE-02 name: Visual Refinement - score: 4 + score: 5 max: 6 passed: true - comment: Spines removed, subtle quarter dividers, no distracting grid + comment: Spines removed, subtle grid, dotted quarter dividers, white stroke + on annotations - id: DE-03 name: Data Storytelling - score: 4 + score: 5 max: 6 passed: true - comment: Fill colors convey momentum, annotations mark key events, dramatic - convergence at end + comment: Clear game narrative through fills, annotations, and convergence spec_compliance: score: 15 max: 15 @@ -111,50 +112,48 @@ review: score: 5 max: 5 passed: true - comment: Correct win probability line chart with filled areas + comment: Correct win probability line chart - id: SC-02 name: Required Features score: 4 max: 4 passed: true - comment: 'All spec features present: 50% line, fills, annotations, quarter - markers, final score' + comment: 'All spec features present: baseline, fills, annotations, score, + quarters' - id: SC-03 name: Data Mapping score: 3 max: 3 passed: true - comment: X = play number, Y = win probability, all data visible + comment: X=play number, Y=win probability, full range shown - id: SC-04 name: Title & Legend score: 3 max: 3 passed: true - comment: Title includes score + spec-id + library + pyplots.ai; legend identifies - both teams + comment: Title includes score and follows spec-id format; legend correct data_quality: - score: 14 + score: 15 max: 15 items: - id: DQ-01 name: Feature Coverage - score: 5 + score: 6 max: 6 passed: true - comment: Shows momentum swings both directions, lead changes, scoring from - both teams + comment: Shows FG/TD events, lead changes, momentum swings, convergence - id: DQ-02 name: Realistic Context score: 5 max: 5 passed: true - comment: Real NFL teams, realistic scoring progression, neutral sports topic + comment: Eagles vs Cowboys NFL game with realistic 27-20 final score - id: DQ-03 name: Appropriate Scale score: 4 max: 4 passed: true - comment: Win probability in realistic range, appropriate scoring shift magnitudes + comment: Realistic probability shifts and natural convergence code_quality: score: 10 max: 10 @@ -164,33 +163,33 @@ review: score: 3 max: 3 passed: true - comment: 'Clean linear flow: imports, data, plot, save' + comment: Clean imports-data-plot-save flow, no functions or classes - id: CQ-02 name: Reproducibility score: 2 max: 2 passed: true - comment: np.random.seed(42) set at top + comment: np.random.seed(42) set - id: CQ-03 name: Clean Imports score: 2 max: 2 passed: true - comment: All three imports used + comment: All imports used - id: CQ-04 name: Code Elegance score: 2 max: 2 passed: true - comment: Appropriate complexity, no fake functionality + comment: Appropriate complexity, no fake UI - id: CQ-05 name: Output & API score: 1 max: 1 passed: true - comment: Saves as plot.png with dpi=300, no deprecated API + comment: Saves as plot.png with dpi=300 library_mastery: - score: 6 + score: 7 max: 10 items: - id: LM-01 @@ -198,16 +197,15 @@ review: score: 4 max: 5 passed: true - comment: Good use of Axes methods, fill_between, annotate with arrowprops, - mpatches + comment: Good ax-based usage; segment loop less idiomatic than LineCollection - id: LM-02 name: Distinctive Features - score: 2 + score: 3 max: 5 - passed: false - comment: fill_between with where is somewhat distinctive but no PathEffects, - FuncFormatter, or other unique features - verdict: REJECTED + passed: true + comment: fill_between with interpolate, patheffects, FuncFormatter, mpatches + legend + verdict: APPROVED impl_tags: dependencies: [] techniques: @@ -221,4 +219,5 @@ impl_tags: - cumulative-sum styling: - alpha-blending + - grid-styling - edge-highlighting