Skip to content

feat(plotly): implement ecdf-basic#5356

Merged
github-actions[bot] merged 4 commits intomainfrom
implementation/ecdf-basic/plotly
Apr 24, 2026
Merged

feat(plotly): implement ecdf-basic#5356
github-actions[bot] merged 4 commits intomainfrom
implementation/ecdf-basic/plotly

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

Implementation: ecdf-basic - python/plotly

Implements the python/plotly version of ecdf-basic.

File: plots/ecdf-basic/implementations/python/plotly.py

Parent Issue: #976


🤖 impl-generate workflow

Regen from quality 92. Addressed:
- brand color — switched from ad-hoc #306998 to Okabe-Ito #009E73
- theme support — light/dark via ANYPLOT_THEME, theme-adaptive chrome
- VQ-06 axis labels — "Finishing Time (minutes)" / "Cumulative Proportion of Runners" with units
- DQ-02 realistic context — marathon finishing times (n=300) replace generic "Value"
- LF-01 library feature — x-unified hover with percentile readout
- title header updated to anyplot.ai and theme-suffixed outputs (plot-{THEME}.{png,html})
@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Apr 24, 2026

AI Review - Attempt 1/3

Image Description

Light render (plot-light.png): Warm off-white #FAF8F1 background — correct, not pure white. Title "Marathon Finishing Times · ecdf-basic · plotly · anyplot.ai" in dark #1A1A17 text, centered, clearly readable. X-axis label "Finishing Time (minutes)" and Y-axis label "Cumulative Proportion of Runners" both in dark INK — readable. Tick labels in #4A4A44 (INK_SOFT) with "min" suffix on x and percentage format on y. Single ECDF step-function line in #009E73 (brand green), width 3.5px, using hv-step shape — covers ~130 to ~370 min producing the characteristic S-curve of a normal distribution. Subtle grid on both axes, left+bottom axis lines only (no top/right spines). All text readable against light background.

Dark render (plot-dark.png): Warm near-black #1A1A17 background — correct, not pure black. Title in off-white #F0EFE8 (INK for dark theme), clearly readable. Axis labels in same light color. Tick labels in #B8B7B0 (INK_SOFT for dark theme) — clearly readable against the dark surface. No dark-on-dark failures observed. Data series is identical #009E73 green ECDF line — correctly unchanged from the light render (only chrome flips). Very subtle light grid (rgba(240,239,232,0.10)) visible. Left and bottom axis lines visible in INK_SOFT.

Both renders pass theme-readability checks. All text is legible in both themes.

Score: 88/100

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

Visual Quality (30/30)

  • VQ-01: Text Legibility (8/8) — All sizes explicitly set: title=28px, axis labels=22px, tick labels=18px. Readable in both themes.
  • VQ-02: No Overlap (6/6) — No overlapping text elements.
  • VQ-03: Element Visibility (6/6) — ECDF line at width=3.5 clearly visible on both backgrounds.
  • VQ-04: Color Accessibility (2/2) — Single series in #009E73, high contrast, CVD-safe.
  • VQ-05: Layout & Canvas (4/4) — Good margins (l=110, r=70, t=110, b=90), canvas well-utilized.
  • VQ-06: Axis Labels & Title (2/2) — "Finishing Time (minutes)" with units; "Cumulative Proportion of Runners" — descriptive.
  • VQ-07: Palette Compliance (2/2) — First series #009E73. Backgrounds #FAF8F1/#1A1A17 correct. All chrome tokens properly applied.

Design Excellence (10/20)

  • DE-01: Aesthetic Sophistication (4/8) — Well-configured theme tokens and Inter font family applied correctly. No distinctive design choices: no area fill under the curve, no percentile reference lines, no emphasis on the central slope.
  • DE-02: Visual Refinement (4/6) — Grid on both axes (appropriate for percentile look-ups), left+bottom axis lines only, generous margins. Some refinement visible but grid-on-both-axes adds visual noise.
  • DE-03: Data Storytelling (2/6) — ECDF displayed raw without emphasis. No reference lines for median/Q1/Q3, no annotation of key percentile values, no visual focal point guiding the viewer.

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) — Correct ECDF step function using shape='hv'. Y-axis 0–1.02. Step increases by 1/n.
  • SC-02: Required Features (4/4) — Step function, y-axis 0–1, grid lines, distinct line style present.
  • SC-03: Data Mapping (3/3) — X = finish time values, Y = cumulative proportion. All data visible.
  • SC-04: Title & Legend (3/3) — Title contains spec-id, library, anyplot.ai. No legend for single series (correct).

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) — 300 points produce a smooth S-curve showing full distribution shape including tails.
  • DQ-02: Realistic Context (5/5) — Marathon finishing times — real-world, neutral, comprehensible domain.
  • DQ-03: Appropriate Scale (4/4) — Mean=240min (4 hours), std=32min — realistic marathon distribution.

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3) — Linear flow: imports → theme tokens → data → ECDF → plot → save. No functions/classes.
  • CQ-02: Reproducibility (2/2) — np.random.seed(42) present.
  • CQ-03: Clean Imports (2/2) — Only os, numpy, plotly.graph_objects — all used.
  • CQ-04: Code Elegance (2/2) — Clean, Pythonic. No over-engineering, no fake UI elements.
  • CQ-05: Output & API (1/1) — Saves plot-{THEME}.png and plot-{THEME}.html. Correct format.

Library Mastery (8/10)

  • LM-01: Idiomatic Usage (5/5) — go.Scatter with line={'shape': 'hv'}, hovertemplate, hovermode='x unified', update_layout — all idiomatic Plotly patterns.
  • LM-02: Distinctive Features (3/5) — Uses Plotly-specific features: hv step function, x-unified hover, hovertemplate with :.1% formatting, HTML export with custom modeBar. Solid but not exceptional.

Score Caps Applied

  • None — DE-01=4 and DE-02=4, so the "correct but boring" cap (DE-01 ≤ 2 AND DE-02 ≤ 2 → max 75) does not apply.

Strengths

  • Perfect theme-adaptive chrome in both renders — all INK/INK_SOFT/PAGE_BG tokens correctly threaded through title, labels, ticks, grid, and backgrounds
  • Correct ECDF step function using Plotly's idiomatic line={'shape': 'hv'} with proper 1/n cumulative proportion calculation
  • Excellent interactive layer: x-unified hover with :.1% percentage formatting and custom modeBar config
  • Realistic marathon data (mean=240min, std=32min) with neutral, comprehensible context
  • All font sizes explicitly set at correct pixel values for 4800×2700 output

Weaknesses

  • No visual storytelling — missing reference lines for key percentiles (Q1 ≈ 218min, median ≈ 240min, Q3 ≈ 262min) that would guide the viewer to statistical landmarks
  • No design focal point — the S-curve inflection region (the steepest part, around the median) is the most information-dense area but receives no visual emphasis
  • Grid on both axes adds unnecessary noise for an ECDF — y-axis-only grid (horizontal lines at 10% intervals) is sufficient for percentile look-ups
  • No area fill under the curve — a semi-transparent #009E73 fill would add depth and better convey cumulative accumulation

Issues Found

  1. DE-01 LOW: Design is well-configured but lacks distinctive choices — no percentile reference lines, no area fill, no emphasis elements
    • Fix: Add dashed vertical reference lines at Q1, median, and Q3 with subtle annotations; optionally add a semi-transparent fill below the ECDF curve
  2. DE-03 LOW: ECDF displayed raw — viewer must identify the median and spread themselves
    • Fix: Add subtle reference lines at the 25th, 50th, and 75th percentile values (both horizontal at y=0.25/0.50/0.75 and vertical at the corresponding x values), creating a "reading guide" that tells the story of the distribution's shape
  3. DE-02 MODERATE: Grid on both axes adds visual noise
    • Fix: Switch to y-axis-only grid (remove xaxis.gridcolor or set x-axis showgrid=False) — horizontal lines are what you trace from the y-axis to read percentiles

AI Feedback for Next Attempt

The implementation is technically strong — fix the design layer to reach approval: (1) Add percentile reference lines at Q1/median/Q3: dashed horizontal lines at y=0.25/0.50/0.75 with corresponding vertical drop lines to x-axis values, annotated with the finish time. This creates visual hierarchy and tells the story of "half of runners finish by X minutes." (2) Switch to y-axis-only grid (remove x-axis grid) to reduce visual noise while keeping percentile read-ability. (3) Optionally add a semi-transparent fill (opacity~0.08) below the ECDF curve using go.Scatter fill='tozeroy' to reinforce the cumulative metaphor.

Verdict: REJECTED

@github-actions github-actions Bot added quality:88 Quality score: 88/100 ai-approved Quality OK, ready for merge labels Apr 24, 2026
@github-actions github-actions Bot merged commit 2d94cdf into main Apr 24, 2026
3 checks passed
@github-actions github-actions Bot deleted the implementation/ecdf-basic/plotly branch April 24, 2026 12:56
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 quality:88 Quality score: 88/100

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants