Skip to content

feat(plotnine): implement lollipop-basic#9599

Merged
MarkusNeusinger merged 6 commits into
mainfrom
implementation/lollipop-basic/plotnine
Jul 1, 2026
Merged

feat(plotnine): implement lollipop-basic#9599
MarkusNeusinger merged 6 commits into
mainfrom
implementation/lollipop-basic/plotnine

Conversation

@github-actions

@github-actions github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Implementation: lollipop-basic - python/plotnine

Implements the python/plotnine version of lollipop-basic.

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

Parent Issue: #934


🤖 impl-generate workflow

github-actions Bot added 2 commits July 1, 2026 05:59
Regen from quality 85. Addressed:
- Canvas size corrected from (16,9) @ dpi=300 to (8,4.5) @ dpi=400 (3200x1800 contract)
- Font sizes updated to library spec (title=12, axis_title=10, axis_text=8, base=7pt)
- DE-01 Aesthetic Sophistication: added size-encoded dots (aes(size="value")) plus
  per-dot value labels via geom_text to create focal emphasis and ranking narrative
- Explicit panel_border=element_blank() replacing implicit theme_minimal removal
- Fixed sys.path circular import issue (plotnine.py shadowing plotnine library)
@claude

claude Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

AI Review - Attempt 1/3

Image Description

Light render (plot-light.png): Warm off-white background (#FAF8F1). Title "lollipop-basic · plotnine · anyplot.ai" in dark (#1A1A17) at 12pt — readable. Y-axis label "Sales (thousands $)" and X-axis label "Product Category" in dark at 10pt — readable. Tick labels in soft-dark (#4A4A44) at 8pt; X-axis tick labels rotated 45° — readable. Ten lollipop stems in brand green (#009E73) extend from baseline (y=0) to proportional-size circular dots (smallest for Automotive/58k, largest for Electronics/245k). Value labels (58k–245k) in soft-dark gray nudged above each dot — small but visible. Subtle horizontal y-axis-only grid lines at alpha≈0.15. Left and bottom axis lines present; no top/right spines. All text is readable against the light background.

Dark render (plot-dark.png): Warm near-black background (#1A1A17). Title in light (#F0EFE8) — readable. Axis labels in light at 10pt — readable. Tick labels in soft-light (#B8B7B0) — readable. Grid adapts to light alpha — subtle but visible. Brand green (#009E73) stems and proportional dots are identical to the light render — color unchanged as required. Value labels in soft-light gray — visible above each dot. No dark-on-dark issues anywhere. Brand green #009E73 reads well on the near-black surface. All text is readable against the dark background.

Both renders pass theme-readability checks. Data colors (brand green) are identical across both themes; only chrome (background, text, grid) flips.

Score: 87/100

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

Visual Quality (29/30)

  • VQ-01: Text Legibility (7/8) — Font sizes explicitly set (title 12pt, axis labels 10pt, tick labels 8pt, geom_text 2.8mm≈8pt). All text readable in both themes. Minor: value labels are small and may challenge readability when scaled to ~400px mobile width.
  • VQ-02: No Overlap (6/6) — No text overlaps. Value labels nudged above dots (nudge_y=16), all elements clear.
  • VQ-03: Element Visibility (6/6) — 10 lollipop stems and size-proportional dots all clearly visible in both themes.
  • VQ-04: Color Accessibility (2/2) — Single-series brand green, no red-green sole-signal issue, CVD-safe.
  • VQ-05: Layout & Canvas (4/4) — Canvas exactly 3200×1800 confirmed; canvas gate not triggered. Good proportions, no overflow.
  • VQ-06: Axis Labels & Title (2/2) — "Sales (thousands $)" includes units; "Product Category" is descriptive.
  • VQ-07: Palette Compliance (2/2) — First (only) series uses #009E73. Backgrounds #FAF8F1 light / #1A1A17 dark. Chrome tokens correctly theme-adaptive.

Design Excellence (11/20)

  • DE-01: Aesthetic Sophistication (5/8) — Size-proportional dots (aes(size="value")) add a second visual dimension above a generic uniform-dot lollipop. Clean theme-adaptive chrome. Above default but not exceptional.
  • DE-02: Visual Refinement (3/6) — Y-axis-only grid (panel_grid_major_x removed), very low alpha (0.15), no panel border. Left/bottom axis lines. Noticeable refinement above defaults.
  • DE-03: Data Storytelling (3/6) — Ascending sort creates a clear ranking narrative. Size encoding reinforces value magnitudes. Value labels give exact numbers. Above defaults, not exceptional.

Spec Compliance (14/15)

  • SC-01: Plot Type (5/5) — Correct lollipop: geom_segment for stems, geom_point for circular dots, vertical orientation.
  • SC-02: Required Features (4/4) — Thin stems from baseline (y=0) to data point, circular dots, vertical orientation, sorted ascending by value.
  • SC-03: Data Mapping (3/3) — Categories on x-axis, values on y-axis, all 10 categories shown with correct values.
  • SC-04: Title & Legend (2/3) — Title is "lollipop-basic · plotnine · anyplot.ai" — missing "python" language component. Required format: lollipop-basic · python · plotnine · anyplot.ai.

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) — Shows stems, dots, baseline connection, value ordering, value labels, size encoding.
  • DQ-02: Realistic Context (5/5) — Product sales by category is realistic and neutral.
  • DQ-03: Appropriate Scale (4/4) — Values 58k–245k in thousands of dollars are plausible for product categories.

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3) — Flat script, no functions or classes.
  • CQ-02: Reproducibility (2/2) — Deterministic data (hardcoded dict), no randomness.
  • CQ-03: Clean Imports (2/2) — All imported symbols are used.
  • CQ-04: Code Elegance (2/2) — Clean plotnine grammar composition, no fake UI, appropriate complexity.
  • CQ-05: Output & API (1/1) — Saves as plot-{THEME}.png via ggsave with correct dpi and dimensions.

Library Mastery (8/10)

  • LM-01: Idiomatic Usage (5/5) — geom_segment + geom_point is the canonical plotnine/ggplot2 lollipop idiom. Proper use of aes(), pd.Categorical for ordered x-axis, ggsave.
  • LM-02: Distinctive Features (3/5) — Uses scale_size_continuous for variable dot sizing, pd.Categorical for controlled x-axis ordering, layered geom composition. Solid but not exceptional.

Score Caps Applied

  • None applied. All VQ/SC/DQ/CQ caps above thresholds; DE-01=5 > 2 so the DE cap does not trigger.

Strengths

  • Correct lollipop idiom: geom_segment (stems) + geom_point (circular dots) is the canonical plotnine/ggplot2 pattern
  • Size-proportional dots (aes(size="value") + scale_size_continuous) add a second visual encoding that reinforces the ranking narrative
  • Perfect data quality: realistic product-sales domain, sorted ascending, value labels for exact readability
  • Full theme-adaptive chrome: PAGE_BG, INK, INK_SOFT tokens applied throughout (background, axis lines, tick labels, grid, title, data labels)
  • Clean plotnine code: flat script, no functions/classes, all imports used, deterministic data, correct ggsave output naming

Weaknesses

  • Title is missing the "python" language indicator — reads lollipop-basic · plotnine · anyplot.ai but must be lollipop-basic · python · plotnine · anyplot.ai per SC-04 format requirement
  • Value labels (geom_text size=2.8mm) are small — consider nudging up to 3.2–3.5mm to improve mobile readability at ~400px scale
  • Top and right spines are still visible (only panel_border=element_blank() is set; axis_line re-draws them on left/bottom but the panel border removal may not fully remove spines in all plotnine versions) — use element_line(color='none') for top/right to ensure they are removed

Issues Found

  1. SC-04 FAIL: Title missing "python" language component
    • Fix: Change title="lollipop-basic · plotnine · anyplot.ai" to title="lollipop-basic · python · plotnine · anyplot.ai" in labs()
  2. VQ-01 MINOR: Value labels slightly small for mobile scale
    • Fix: Increase geom_text(size=2.8, ...) to size=3.2 or size=3.5 for better readability when scaled down

AI Feedback for Next Attempt

Fix the title to include "python": "lollipop-basic · python · plotnine · anyplot.ai". Optionally increase geom_text size from 2.8 to 3.2–3.5mm for better mobile readability. The core lollipop implementation, theme adaptation, data choice, and code structure are all solid — only the title format needs correction.

Verdict: APPROVED

@github-actions github-actions Bot added quality:87 Quality score 87/100 ai-rejected Quality not OK, triggers update labels Jul 1, 2026
@github-actions github-actions Bot added ai-attempt-1 First repair attempt and removed ai-rejected Quality not OK, triggers update labels Jul 1, 2026
Attempt 1/3 - fixes based on AI review
@github-actions

github-actions Bot commented Jul 1, 2026

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 Jul 1, 2026

Copy link
Copy Markdown
Contributor

AI Review - Attempt 2/3

Image Description

Light render (plot-light.png): A lollipop chart on a warm off-white (#FAF8F1) background showing 10 product categories sorted ascending left to right (Automotive=58k to Electronics=245k). Brand green (#009E73) stems (thin vertical lines from y=0) and circular markers are used throughout. Marker size scales with value via size aesthetic — smallest for Automotive/Garden, largest for Electronics. Value labels (e.g. "58k", "245k") appear above each dot in INK_SOFT dark gray. Title "lollipop-basic · python · plotnine · anyplot.ai" in dark ink occupies ~65% of plot width. Axis labels "Product Category" (x) and "Sales (thousands $)" (y) are clearly readable. Rotated 45° category tick labels are legible. Subtle horizontal gridlines (alpha=0.15) only, no x-grid. All text is readable against the light background — no light-on-light issues.

Dark render (plot-dark.png): Same chart rendered on warm near-black (#1A1A17) background. Title and axis labels are now in near-white (#F0EFE8) — clearly visible against the dark surface. Tick labels appear in lighter gray (#B8B7B0). Data colors are identical to the light render: all lollipop stems and markers remain brand green (#009E73). Size encoding preserved. Value labels above dots are in the lighter INK_SOFT token — readable. Grid lines are subtly visible with adapted opacity. No dark-on-dark failures found — all chrome elements correctly adapted via INK/INK_SOFT tokens. Brand green reads well on the dark surface.

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

Score: 84/100

Category Score Max
Visual Quality 27 30
Design Excellence 11 20
Spec Compliance 15 15
Data Quality 15 15
Code Quality 10 10
Library Mastery 6 10
Total 84 100

Visual Quality (27/30)

  • VQ-01: Text Legibility (7/8) — Title (12pt), axis labels (10pt), tick labels (8pt) explicitly set and readable in both themes. Value labels (geom_text size=2.8mm) are small but within spec at full resolution.
  • VQ-02: No Overlap (5/6) — No overlapping text or data elements. Middle-section labels (Books, Sports, Groceries) are close but do not collide.
  • VQ-03: Element Visibility (5/6) — Stems and markers clearly visible. Size range [2,7] effective for ranking. Smallest dots (Automotive, Garden) are visible but noticeably compact.
  • VQ-04: Color Accessibility (2/2) — Single brand green series; no CVD concerns. Good contrast on both backgrounds.
  • VQ-05: Layout & Canvas (4/4) — Canvas gate passed (3200×1800). Title ~65% plot width. No overflow or clipping. Rotated x-tick labels have adequate margin.
  • VQ-06: Axis Labels & Title (2/2) — X: "Product Category", Y: "Sales (thousands $)" with units. Title matches required format.
  • VQ-07: Palette Compliance (2/2) — Single series uses brand green #009E73. Light bg #FAF8F1, dark bg #1A1A17. Both renders theme-correct.

Design Excellence (11/20)

  • DE-01: Aesthetic Sophistication (5/8) — Above default. Size encoding adds meaningful visual hierarchy; warm palette is consistent. Single-color design across all 10 categories limits further differentiation.
  • DE-02: Visual Refinement (3/6) — Slightly above default. theme_minimal() removes chartjunk; horizontal-only gridlines (alpha=0.15) are appropriately subtle; x-grid and minor grid removed. No tick-mark removal or further spine polish.
  • DE-03: Data Storytelling (3/6) — Slightly above default. Ascending sort creates a clear ranking narrative. Size encoding reinforces value hierarchy. No additional emphasis on top/bottom performers or annotations.

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) — Correct lollipop chart: geom_segment for stems, geom_point for circular markers.
  • SC-02: Required Features (4/4) — Stems from y=0 to value, circular markers, vertical orientation, data sorted by value.
  • SC-03: Data Mapping (3/3) — Category on x-axis, value on y-axis. All 10 categories displayed.
  • SC-04: Title & Legend (3/3) — Title matches required format. No legend (single series) — appropriate.

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) — Full lollipop anatomy demonstrated: stems, markers, sorting, size encoding, data labels.
  • DQ-02: Realistic Context (5/5) — Product sales by category — neutral, real-world plausible data.
  • DQ-03: Appropriate Scale (4/4) — Sales values $58k–$245k are realistic; range provides good visual spread.

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3) — Top-level script, no functions or classes.
  • CQ-02: Reproducibility (2/2) — Hardcoded deterministic data.
  • CQ-03: Clean Imports (2/2) — All 14 plotnine imports are used.
  • CQ-04: Code Elegance (2/2) — Clean code; sys.path manipulation is justified to avoid circular import with file named plotnine.py.
  • CQ-05: Output & API (1/1) — ggsave outputs to plot-{THEME}.png using current API.

Library Mastery (6/10)

  • LM-01: Idiomatic Usage (4/5) — Proper ggplot grammar: aes() mapping, layered geoms, theme() customization. pd.Categorical for axis ordering is the correct plotnine pattern.
  • LM-02: Distinctive Features (2/5) — Uses the standard geom_segment + geom_point + geom_text lollipop pattern (widely known ggplot2 idiom). scale_size_continuous is a nice addition. No more advanced plotnine-specific features (stats, coord transforms, scale transformations, faceting) exploited.

Score Caps Applied

  • None — no caps triggered.

Strengths

  • Full spec compliance: correct lollipop anatomy (geom_segment stems + geom_point markers), sorted data, vertical orientation
  • Brand green #009E73 used consistently; theme adaptation is correct in both light and dark renders
  • Size aesthetic mapped to value adds redundant encoding and reinforces the ranking hierarchy
  • Value labels precisely annotate each dot; ascending sort creates a clear ranking narrative
  • Excellent code quality: clean imports, deterministic data, idiomatic plotnine grammar

Weaknesses

  • Design Excellence is moderate — single brand-green palette for all 10 lollipops; no additional styling elements add intentional hierarchy beyond size encoding (e.g. no emphasis color for top/bottom performer)
  • LM-02 underperforms — the implementation uses standard ggplot2 lollipop layering without exploiting more distinctive plotnine capabilities (e.g. stat transforms, coord_flip for long labels, advanced scale features)
  • Visual refinement is basic — no tick-mark removal, axis line could be cleaned further
  • Smallest lollipops (Automotive=58k, Garden=72k) have noticeably compact dots due to size range=[2,7]; these are visible but less prominent at smaller display sizes

Issues Found

  1. DE-01 MODERATE: Single-color design limits sophistication beyond size encoding.
    • Fix: Consider highlighting the top performer (Electronics) with a slightly different treatment (e.g. label in INK instead of INK_SOFT, or a subtle background annotation) to draw the viewer's eye.
  2. LM-02 LOW: Standard lollipop pattern without distinctive plotnine-specific features.
    • Fix: Consider using + reordering as an alternative idiomatic plotnine approach, or add elements that showcase plotnine's statistical layer capabilities.

AI Feedback for Next Attempt

The implementation is solid and fully spec-compliant. To push the score higher: (1) Add a subtle emphasis on the top performer (Electronics) — e.g. bolder label or a light annotation box — to create a stronger focal point and improve DE-03. (2) Increase the minimum dot size in scale_size_continuous range (e.g. [3, 8]) so smaller lollipop heads remain prominent at smaller display widths. (3) Consider removing axis tick marks explicitly (axis_ticks=element_blank()) for additional visual refinement (DE-02). These changes would push DE into the 14–16 range.

Verdict: APPROVED

@github-actions github-actions Bot added quality:84 Quality score 84/100 ai-approved Quality OK, ready for merge and removed quality:87 Quality score 87/100 labels Jul 1, 2026
@MarkusNeusinger MarkusNeusinger merged commit d63fcd0 into main Jul 1, 2026
@MarkusNeusinger MarkusNeusinger deleted the implementation/lollipop-basic/plotnine branch July 1, 2026 06:13
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:84 Quality score 84/100

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant