Skip to content

feat(plotnine): implement funnel-basic#5429

Merged
github-actions[bot] merged 4 commits intomainfrom
implementation/funnel-basic/plotnine
Apr 26, 2026
Merged

feat(plotnine): implement funnel-basic#5429
github-actions[bot] merged 4 commits intomainfrom
implementation/funnel-basic/plotnine

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

Implementation: funnel-basic - python/plotnine

Implements the python/plotnine version of funnel-basic.

File: plots/funnel-basic/implementations/python/plotnine.py

Parent Issue: #789


🤖 impl-generate workflow

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Apr 26, 2026

AI Review - Attempt 1/3

Image Description

Light render (plot-light.png): A clean funnel chart on a warm off-white #FAF8F1 background with five trapezoidal segments narrowing from top to bottom. Stage order: Awareness (brand green #009E73), Interest (vermillion #D55E00), Consideration (blue #0072B2), Intent (reddish-purple #CC79A7), and Purchase (amber #E69F00). Each segment carries a two-line bold label with stage name, absolute value, and percentage (e.g. "Awareness / 1,000 · 100%"). White text is used for the first four segments; dark ink text on the amber Purchase segment. Title "funnel-basic · plotnine · anyplot.ai" is centered at the top in dark ink. All text is clearly readable against the light background. No axis labels, ticks, or grid — void theme. PASS.

Dark render (plot-dark.png): Identical chart on a near-black #1A1A17 background. The five Okabe-Ito data colors are unchanged (brand green, vermillion, blue, reddish-purple, amber) — only chrome flips. Title renders in light cream #F0EFE8 and is clearly readable. Segment labels for Awareness–Intent are white on their respective fills, readable in both themes. The Purchase segment (amber #E69F00) uses INK token as text color, which resolves to #F0EFE8 in dark mode — light cream on amber gives approximately 2.2:1 contrast, below WCAG AA. The text remains readable due to bold weight, but contrast is sub-optimal. Separator gaps between segments switch from off-white (light) to near-black (dark), working correctly. Legibility verdict: PASS overall, with a minor contrast note on the Purchase label.

Both renders confirmed. No dark-on-dark failures for the title or primary labels. One sub-threshold contrast on Purchase dark-mode text.

Score: 87/100

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

Visual Quality (27/30)

  • VQ-01: Text Legibility (7/8) — Title explicitly at 24pt ✓; data labels at 14pt are below the recommended 16pt for secondary text, though readable
  • VQ-02: No Overlap (6/6) — All labels perfectly centered within their segments
  • VQ-03: Element Visibility (6/6) — All five segments clearly visible including the small Purchase rectangle
  • VQ-04: Color Accessibility (1/2) — Okabe-Ito is CVD-safe; white-on-fill contrast is good for four segments, but light cream (#F0EFE8) on amber (#E69F00) in dark mode is ~2.2:1, below WCAG AA
  • VQ-05: Layout & Canvas (3/4) — 16:9 canvas used well; funnel fills ~60% of height and ~80% of width at top; minor dead space in lower portion below Purchase
  • VQ-06: Axis Labels & Title (2/2) — Title in required format; no axis labels needed for funnel type
  • VQ-07: Palette Compliance (2/2) — First stage is #009E73 ✓; subsequent stages follow Okabe-Ito canonical order ✓; backgrounds #FAF8F1 / #1A1A17 ✓; chrome flips correctly ✓

Design Excellence (13/20)

  • DE-01: Aesthetic Sophistication (5/8) — Above configured defaults: Okabe-Ito applied correctly, smart text-contrast logic (dark ink on light fill), bold labels, void theme. Not quite "strong design" — typography hierarchy is flat and there's no visual emphasis on the insight (e.g., the large Awareness→Interest drop-off isn't called out)
  • DE-02: Visual Refinement (4/6) — theme_void removes all axes/spines/grid; polygon gaps provide clean segment separation; generous whitespace. More than minimal but not every detail polished
  • DE-03: Data Storytelling (4/6) — Dual labels (absolute + %) help quantify drop-offs; funnel shape encodes magnitude visually. The biggest story (60% retention at first step, then halving each stage) is visible but not emphasized — no focal point or annotation highlighting the sharpest transitions

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) — Correct trapezoidal funnel narrowing proportionally top-to-bottom
  • SC-02: Required Features (4/4) — Distinct colors per stage ✓; value + percentage labels ✓; widths proportional to value/max_value ✓; stages top→bottom order ✓
  • SC-03: Data Mapping (3/3) — Stages correctly ordered largest-to-smallest; all data visible
  • SC-04: Title & Legend (3/3) — "funnel-basic · plotnine · anyplot.ai" ✓; legend suppressed (guide=None), replaced by in-chart labels — appropriate

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) — Five stages with varied drop-off rates fully cover the funnel chart concept
  • DQ-02: Realistic Context (5/5) — Classic sales/marketing funnel (Awareness → Purchase) with plausible, neutral values
  • DQ-03: Appropriate Scale (4/4) — Values 1000 → 100 with realistic intermediate steps; percentages accurately computed

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3) — No functions or classes; clean linear flow
  • CQ-02: Reproducibility (2/2) — Fully deterministic (no random operations)
  • CQ-03: Clean Imports (2/2) — All imports used; sys/os are standard library
  • CQ-04: Code Elegance (2/2) — Clean polygon construction loop; no over-engineering or fake UI
  • CQ-05: Output & API (1/1) — Saves as plot-{THEME}.png

Library Mastery (7/10)

  • LM-01: Idiomatic Usage (4/5) — Grammar of graphics correctly composed throughout: geom_polygon + geom_text + scale_color_identity() + scale_fill_manual() + theme(); scale_color_identity() for per-row text colors is idiomatic and clever
  • LM-02: Distinctive Features (3/5) — scale_color_identity() with per-row aesthetic mapping is a plotnine-distinctive pattern; geom_polygon for a non-native chart type shows grammar understanding; scale_y_reverse() integration is clean. Not quite unique enough to warrant 4+

Score Caps Applied

  • None

Strengths

  • Perfect spec compliance: all spec features (trapezoidal segments, proportional widths, dual value+% labels, distinct Okabe-Ito colors) implemented correctly
  • Creative use of geom_polygon within plotnine's grammar of graphics to build a non-native chart type without falling back to matplotlib
  • Smart per-segment text contrast: dark INK on the light amber (#E69F00) fill in light mode — shows accessibility awareness
  • Both themes render correctly with the right backgrounds and chrome tokens

Weaknesses

  • VQ-04: Dark mode Purchase label (#F0EFE8 on #E69F00) has ~2.2:1 contrast — below WCAG AA; should use dark ink for the Purchase segment regardless of theme
  • DE-01/DE-03: No visual emphasis or focal point — the most dramatic drop-offs (Awareness→Interest: 40% loss) are not highlighted; consider a slight size variation on the label or a drop-shadow callout to anchor the viewer's eye
  • VQ-01: Data labels at size=14pt are below the 16pt recommendation for secondary text at 4800×2700px; bump to at least 16pt

Issues Found

  1. VQ-04 LOW: Dark mode Purchase text contrast (#F0EFE8 on #E69F00 ≈ 2.2:1) is sub-threshold
    • Fix: For the Purchase (amber) segment, always use dark ink (#1A1A17) regardless of theme — it has adequate contrast in both light and dark mode against #E69F00
  2. DE-03 LOW: No visual emphasis on key insight — the steep funnel drop is not drawn out
    • Fix: Add typographic hierarchy (larger stage-name text vs. value text), or a subtle annotation showing the % drop between the first two stages
  3. VQ-01 MINOR: Data label size=14pt below the 16pt secondary-text recommendation
    • Fix: Change geom_text size from 14 to 16

AI Feedback for Next Attempt

Three targeted fixes: (1) Fix dark-mode Purchase text contrast — always use dark ink (#1A1A17) for the amber (#E69F00) segment since it has adequate contrast in both themes; (2) Bump geom_text size from 14 to 16pt to meet secondary-text sizing; (3) Add a subtle typographic hierarchy (two-size label: larger stage name, smaller value/pct) or a percentage-drop annotation between stages to create a focal point and improve storytelling.

Verdict: REJECTED

@github-actions github-actions Bot added quality:87 Quality score 87/100 ai-approved Quality OK, ready for merge labels Apr 26, 2026
@github-actions github-actions Bot merged commit b12ba37 into main Apr 26, 2026
3 checks passed
@github-actions github-actions Bot deleted the implementation/funnel-basic/plotnine branch April 26, 2026 05:50
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:87 Quality score 87/100

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants