Skip to content

feat(matplotlib): implement ecdf-basic#9484

Merged
MarkusNeusinger merged 6 commits into
mainfrom
implementation/ecdf-basic/matplotlib
Jun 25, 2026
Merged

feat(matplotlib): implement ecdf-basic#9484
MarkusNeusinger merged 6 commits into
mainfrom
implementation/ecdf-basic/matplotlib

Conversation

@github-actions

Copy link
Copy Markdown
Contributor

Implementation: ecdf-basic - python/matplotlib

Implements the python/matplotlib version of ecdf-basic.

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

Parent Issue: #976


🤖 impl-generate workflow

github-actions Bot added 2 commits June 25, 2026 09:27
Regen from quality 89. Addressed:
- Canvas corrected: figsize=(8,4.5) dpi=400 (was figsize=(16,9) dpi=300) → 3200×1800
- Removed bbox_inches='tight' (was causing canvas drift)
- Font sizes updated to library spec: title 12pt, labels 10pt, ticks 8pt (was 24/20/16)
- Grid alpha corrected to 0.15 (was 0.10)
- Domain changed to IoT sensor temperatures (bimodal: offices 22°C vs server rooms 18.5°C) per change request (altair+letsplot both used API response times)
- Reference guides changed to quartiles Q1/Q2/Q3 with crosshairs
- subplots_adjust replaces tight_layout for pixel-accurate canvas
@claude

claude Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

AI Review - Attempt 1/3

Image Description

Light render (plot-light.png): The ECDF step function is rendered on a warm off-white (#FAF8F1) background. The brand green (#009E73) step curve rises from ~17°C to ~26°C on the x-axis, with "Cumulative Proportion" on the y-axis (0 to 1). Three quartile reference lines (Q1, Q2, Q3) are shown as faint dotted gray cross-hairs, with muted-gray annotations reading "Q1 18.8°C", "Q2 20.7°C", and "Q3 22.4°C". The title "Sensor Temperatures · ecdf-basic · python · matplotlib · anyplot.ai" and axis labels "Temperature (°C)" / "Cumulative Proportion" are all rendered in dark ink. Subtle horizontal grid lines assist percentile reading. Top and right spines are removed. All text is readable against the light background — no legibility issues.

Dark render (plot-dark.png): The same plot on a warm near-black (#1A1A17) background. The ECDF line color is identical brand green (#009E73) — data color unchanged between themes. The quartile annotations and reference dotted lines appear in a light muted gray (#A8A79F) that is clearly readable against the dark background. Title, axis labels, and tick labels are all rendered in a warm near-white (#F0EFE8 / #B8B7B0) with good contrast. No dark-on-dark issues detected — all text is legible. Grid lines flip to light-on-dark at the same low opacity. Both renders are theme-correct and fully readable.

Score: 89/100

Category Score Max
Visual Quality 29 30
Design Excellence 11 20
Spec Compliance 15 15
Data Quality 15 15
Code Quality 10 10
Library Mastery 9 10
Total 89 100

Visual Quality (29/30)

  • VQ-01: Text Legibility (7/8) — Title at 12pt, axis labels at 10pt, tick labels and annotations at 8pt; all readable in both themes. Minor: quartile annotations at fontsize=8 are at the minimum threshold for mobile scaling.
  • VQ-02: No Overlap (6/6) — No overlapping text, data, or annotation elements
  • VQ-03: Element Visibility (6/6) — ECDF line at linewidth=2.5 in brand green is clearly visible; quartile reference lines intentionally subtle
  • VQ-04: Color Accessibility (2/2) — Single-series in CVD-safe brand green; no red-green conflict
  • VQ-05: Layout & Canvas (4/4) — Canvas gate passed (3200×1800 correct); generous margins via subplots_adjust; balanced proportions
  • VQ-06: Axis Labels & Title (2/2) — "Temperature (°C)" with units, "Cumulative Proportion" — both descriptive; title includes descriptive prefix
  • VQ-07: Palette Compliance (2/2) — Brand green #009E73 for single series; backgrounds #FAF8F1/#1A1A17 correct; chrome fully theme-adaptive

Design Excellence (11/20)

  • DE-01: Aesthetic Sophistication (5/8) — Above generic defaults: correct Imprint palette, theme-adaptive chrome, thoughtful bimodal dataset revealing interesting distribution shape. No exceptional design innovation beyond expected structure.
  • DE-02: Visual Refinement (3/6) — Top/right spines removed; y-axis-only grid at alpha=0.15 is appropriately subtle; generous whitespace. No single-series legend (correct). Correct but not highly refined beyond baseline requirements.
  • DE-03: Data Storytelling (3/6) — Quartile reference guides (Q1/Q2/Q3) aid percentile reading and add analytical value. Bimodal shape is visible in the ECDF curve. Story is functional but not exceptionally guided — the two modes (office vs server room) are not highlighted explicitly.

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) — Correct ECDF step function via ax.ecdf(); y-axis 0–1; step increments by 1/n at each point
  • SC-02: Required Features (4/4) — Step function ✓, y-axis 0–1 range ✓, grid lines for percentile reading ✓, distinct line style ✓
  • SC-03: Data Mapping (3/3) — X-axis: temperature values; Y-axis: cumulative proportion; all 250 data points represented
  • SC-04: Title & Legend (3/3) — Title "Sensor Temperatures · ecdf-basic · python · matplotlib · anyplot.ai" matches required format; single-series legend correctly omitted

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) — Full ECDF with quartile cross-hairs; bimodal mixture demonstrates multiple distribution characteristics
  • DQ-02: Realistic Context (5/5) — IoT sensor temperature data (office 22°C ± 1.8, server rooms 18.5°C ± 0.9) is a plausible, neutral real-world scenario
  • DQ-03: Appropriate Scale (4/4) — 250 points (within 50–500 spec range); temperature range 16–27°C realistic for indoor environments

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3) — Linear script, no functions or classes
  • CQ-02: Reproducibility (2/2) — np.random.seed(7) set
  • CQ-03: Clean Imports (2/2) — Only os, matplotlib.pyplot, numpy — all used
  • CQ-04: Code Elegance (2/2) — Clean, idiomatic; zip with strict=True; title fontsize scaling formula applied
  • CQ-05: Output & API (1/1) — Saves as plot-{THEME}.png; no bbox_inches='tight'; current ax.ecdf() API

Library Mastery (9/10)

  • LM-01: Idiomatic Usage (5/5) — Uses ax.ecdf() (matplotlib 3.8+ native method); follows Axes-method pattern; fig.subplots_adjust for layout
  • LM-02: Distinctive Features (4/5) — ax.ecdf() is a distinctive matplotlib-native feature. Quartile cross-hairs use ax.plot() + ax.annotate() appropriately. One point held for limited showcase of additional matplotlib-specific capabilities.

Score Caps Applied

  • None

Strengths

  • Uses matplotlib's native ax.ecdf() method — idiomatic, correct, and showcases a relatively new matplotlib feature (3.8+)
  • Thoughtful bimodal dataset (IoT sensor temperatures mixing office and server rooms) that creates an analytically interesting distribution
  • Quartile reference guides (Q1/Q2/Q3) add strong practical value for percentile reading directly from the ECDF
  • Complete, correct theme-adaptive chrome — all text, spines, and grid tokens properly flip between light and dark renders
  • Correct canvas (3200×1800), no bbox_inches='tight', proper Imprint palette and background colors

Weaknesses

  • Design Excellence is functional but not exceptional — visual hierarchy could be strengthened (e.g. a subtle fill under the ECDF curve, or muted vertical bands marking the two modes)
  • The bimodal structure (office vs server rooms) is not explicitly highlighted — adding a secondary annotation or subtle shading to distinguish the two populations would elevate the storytelling
  • Quartile annotation fontsize=8 is at the minimum threshold; consider 9pt for better readability at smaller display sizes

Issues Found

  1. DE-03 MODERATE: The bimodal distribution is not visually emphasized — the two populations (office temperatures centered at 22°C, server rooms at 18.5°C) are implicit in the ECDF shape but not called out
    • Fix: Consider adding light shaded regions or a text annotation noting the two modes to make the bimodal structure immediately apparent to the reader
  2. DE-02 MODERATE: Visual refinement is correct but conservative — could add a subtle alpha fill under the ECDF curve for more visual weight
    • Fix: ax.fill_between() below the ECDF line at alpha~0.1 would add depth without cluttering

AI Feedback for Next Attempt

The implementation is technically excellent and spec-complete. To raise Design Excellence: (1) add a subtle fill_between under the ECDF curve (alpha=0.08–0.12) to give the step function more visual weight; (2) annotate or shade the two distinct population modes to make the bimodal story immediately readable; (3) consider increasing quartile annotation fontsize from 8pt to 9pt. All other aspects are strong — preserve the bimodal dataset, quartile guides, ax.ecdf() usage, and theme-adaptive chrome.

Verdict: APPROVED

@github-actions github-actions Bot added quality:89 Quality score 89/100 ai-rejected Quality not OK, triggers update labels Jun 25, 2026
@github-actions github-actions Bot added ai-attempt-1 First repair attempt and removed ai-rejected Quality not OK, triggers update labels Jun 25, 2026
Attempt 1/3 - fixes based on AI review
@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

claude Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

AI Review - Attempt 2/3

Image Description

Light render (plot-light.png): The plot renders on a warm off-white #FAF8F1 surface. The title "Sensor Temperatures · ecdf-basic · python · matplotlib · anyplot.ai" appears in dark #1A1A17 ink at ~72% canvas width — well-proportioned for the 67-char string at 12pt. The ECDF step curve is rendered in brand green #009E73 at linewidth=2.5, sweeping from ~16.5°C to ~26.5°C with a characteristic bimodal S-curve shape. A very subtle green fill (alpha=0.10) sits beneath the curve. Three quartile reference guides (dotted lines) mark Q1=18.8°C, Q2=20.7°C, Q3=22.4°C with annotations in INK_MUTED. Dashed vertical lines at 18.5°C and 22.0°C are labelled "Server rooms" and "Offices" near the bottom. Axis labels "Temperature (°C)" and "Cumulative Proportion" in dark ink, tick labels in #4A4A44. L-spine (top/right removed), subtle y-axis-only horizontal grid. All text clearly readable against the light background.

Dark render (plot-dark.png): The same plot on warm near-black #1A1A17. The title and axis labels flip to light #F0EFE8; tick labels to #B8B7B0 — all fully legible with no dark-on-dark failures. The ECDF line remains #009E73 (identical to light render). The fill-under-curve is barely perceptible at alpha=0.10 but does not harm readability. Quartile annotations and mode labels render in #A8A79F, clearly visible. Spines in INK_SOFT, grid lines appropriately subtle. Data colors are identical to the light render; only chrome flipped.

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

Score: 91/100

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

Visual Quality (30/30)

  • VQ-01: Text Legibility (8/8) — All font sizes explicitly set: title_fs=12 (computed from 67-char string), xlabel/ylabel=10pt, ticks=8pt, annotations=8–9pt. Readable in both themes, proportions balanced.
  • VQ-02: No Overlap (6/6) — No overlapping elements; quartile annotations offset from data intersections; mode labels well-separated.
  • VQ-03: Element Visibility (6/6) — ECDF line at linewidth=2.5 clearly prominent; 250-point medium-density dataset well-suited for step-function display.
  • VQ-04: Color Accessibility (2/2) — Single series in brand green #009E73 on warm bg; good luminance contrast; CVD-safe.
  • VQ-05: Layout & Canvas (4/4) — Canvas gate passed; subplots_adjust(left=0.09, right=0.97, top=0.92, bottom=0.12) provides balanced margins; no clipping.
  • VQ-06: Axis Labels & Title (2/2) — "Temperature (°C)" with units; "Cumulative Proportion" descriptive.
  • VQ-07: Palette Compliance (2/2) — ECDF and fill use BRAND=#009E73 (first series). Backgrounds #FAF8F1/#1A1A17. Full theme-adaptive chrome via INK/INK_SOFT/INK_MUTED tokens. Data colors identical across both renders.

Design Excellence (13/20)

  • DE-01: Aesthetic Sophistication (5/8) — Above configured-default (4): bimodal data concept + fill-under-curve + quartile guides + mode markers show clear design intent. Not yet FiveThirtyEight-level polish.
  • DE-02: Visual Refinement (4/6) — Good: L-spine (top/right removed), y-axis-only grid (alpha=0.15, linewidth=0.8), explicit subplots_adjust whitespace management. Stops short of "every detail polished."
  • DE-03: Data Storytelling (4/6) — Good: bimodal structure + mode labels ("Server rooms"/"Offices") + quartile annotations create a narrative arc; viewer identifies the two populations immediately.

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) — Correct ECDF via ax.ecdf(); step function increases 1/n at each observation.
  • SC-02: Required Features (4/4) — All spec features present: step function, Y-axis 0–1, distinct line, grid lines. Quartile guides and mode markers as enhancements.
  • SC-03: Data Mapping (3/3) — Temperature on X, cumulative proportion (0–1) on Y; full data range visible.
  • SC-04: Title & Legend (3/3) — Title matches {Descriptive} · ecdf-basic · python · matplotlib · anyplot.ai format. Single-series: no legend (correct).

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) — Bimodal distribution demonstrates shape, spread, multiple populations, and percentile readability.
  • DQ-02: Realistic Context (5/5) — IoT sensor temperatures in offices (22°C) and server rooms (18.5°C): neutral, domain-appropriate scenario.
  • DQ-03: Appropriate Scale (4/4) — Office ~22°C (sd=1.8), server room ~18.5°C (sd=0.9) are plausible real-world values; 250 observations within 50–500 recommended range.

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3) — Linear Imports → Data → Plot → Save; no functions or classes.
  • CQ-02: Reproducibility (2/2) — np.random.seed(7).
  • CQ-03: Clean Imports (2/2) — Only os, matplotlib.pyplot, numpy — all used.
  • CQ-04: Code Elegance (2/2) — Clean Pythonic code; zip(..., strict=True) is idiomatic Python 3.10+.
  • CQ-05: Output & API (1/1) — Saves as plot-{THEME}.png; ax.ecdf() is current matplotlib 3.8+ API; no bbox_inches='tight'.

Library Mastery (8/10)

  • LM-01: Idiomatic Usage (5/5) — ax.ecdf() is the high-level native API; axes methods throughout; subplots_adjust over tight_layout.
  • LM-02: Distinctive Features (3/5) — ax.ecdf() is distinctive to matplotlib 3.8+ (unavailable elsewhere without manual ECDF computation); fill_between with step='post' mirrors the ECDF step mode idiomatically.

Score Caps Applied

  • None — no caps triggered (VQ-02=6, VQ-03=6, SC-01=5, DQ-02=5, DE-01=5>2, CQ-04=2>0).

Strengths

  • ax.ecdf() is matplotlib-native (3.8+), not available in other libraries without manual ECDF computation
  • Bimodal IoT sensor temperature data with mode markers creates an immediately legible narrative
  • Quartile reference guides (Q1/Q2/Q3) directly support the spec requirement for percentile readability
  • Subtle fill-under-curve (step='post', alpha=0.10) adds visual depth without distracting from the ECDF line
  • Perfect theme-adaptive chrome: both renders fully readable with no dark-on-dark failures
  • All font sizes explicitly set with proportional scaling; canvas exactly 3200×1800 px

Weaknesses

  • Q-annotations use xytext=(5, 5) offset points — very small clearance that places text close to the ECDF curve; a larger offset (e.g. (8, 8) or (10, 10)) or a callout line would improve separation
  • Fill-under-curve alpha=0.10 is nearly invisible in the dark render; alpha=0.13–0.15 would make it readable in both themes without looking heavy
  • LM-02 could be strengthened by using ax.ecdf()'s complementary=False/True parameter to showcase the full API surface

Issues Found

  1. DE-02 MINOR: Grid is y-axis-only at alpha=0.15 which is correct and good, but whitespace is only managed by subplots_adjust — no further spacing refinements
    • Fix (optional): Minor — no repair needed at this score
  2. LM-02 MINOR: The ax.ecdf() usage is correct but doesn't explore the function's full API
    • Fix (optional): Minor — not worth a repair cycle

AI Feedback for Next Attempt

Score 91/100 — APPROVED at attempt 2 (threshold ≥ 80). No repair needed. The implementation is production-quality with excellent spec compliance, data quality, code quality, and visual quality all at maximum. Design excellence is good (13/20) with above-average storytelling and refinement. The only meaningful improvement opportunities are slightly increasing the Q-annotation offsets for better ECDF-line separation and bumping the fill alpha for dark-render visibility, but neither warrants a repair cycle.

Verdict: APPROVED

@github-actions github-actions Bot added quality:91 Quality score 91/100 ai-approved Quality OK, ready for merge and removed quality:89 Quality score 89/100 labels Jun 25, 2026
@MarkusNeusinger MarkusNeusinger merged commit c729120 into main Jun 25, 2026
@MarkusNeusinger MarkusNeusinger deleted the implementation/ecdf-basic/matplotlib branch June 25, 2026 09:46
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:91 Quality score 91/100

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant