Skip to content

feat(plotnine): implement maze-circular#7491

Merged
MarkusNeusinger merged 6 commits into
mainfrom
implementation/maze-circular/plotnine
May 20, 2026
Merged

feat(plotnine): implement maze-circular#7491
MarkusNeusinger merged 6 commits into
mainfrom
implementation/maze-circular/plotnine

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

Implementation: maze-circular - python/plotnine

Implements the python/plotnine version of maze-circular.

File: plots/maze-circular/implementations/python/plotnine.py

Parent Issue: #3804


🤖 impl-generate workflow

github-actions Bot added 2 commits May 20, 2026 07:48
Regen from quality 91. Addressed:
- Fixed save filename: plot.png → plot-{THEME}.png (theme-suffixed)
- Added ANYPLOT_THEME env var and full theme-adaptive chrome (PAGE_BG, INK, INK_SOFT)
- Fixed title: "pyplots.ai" → "anyplot.ai", added language token "python"
- Fixed canvas: figsize=(12,12) dpi=300 → figsize=(6,6) dpi=400 (style guide 1:1 square)
- Applied theme-adaptive wall color (INK) and backgrounds (element_rect with PAGE_BG)
- Wired difficulty parameter to n_rings (easy=5, medium=7, hard=9 rings)
- Widened entry gap from 0.8× to 1.2× sector width for visual prominence
- Preserved DFS maze algorithm, coord_fixed, and sector scaling (all strengths)
- Goal marker now uses GOAL_COLOR=#009E73 (Okabe-Ito position 1)
@claude
Copy link
Copy Markdown
Contributor

claude Bot commented May 20, 2026

AI Review - Attempt 1/3

Image Description

Light render (plot-light.png): Warm off-white background (#FAF8F1). A circular maze with 7 concentric rings drawn in dark near-black ink (#1A1A17), connected by radial passages. The center shows a green dot (GOAL_COLOR #009E73) with bold "GOAL" label in matching green above it. Outside the outer ring at the 3 o'clock position, a soft gray "START" label marks the entry gap. The title "maze-circular · python · plotnine · anyplot.ai" is bold and centered at the top. All text is clearly readable against the light background. No axis elements — theme_void used appropriately.

Dark render (plot-dark.png): Near-black background (#1A1A17). Same circular maze but walls render as white/light lines on dark background — correct theme inversion. The GOAL dot and label remain in #009E73 (identical to light render). The "START" label appears in a soft light gray (INK_SOFT #B8B7B0). The title is rendered in light off-white text, clearly legible. No dark-on-dark failures observed. All text is readable against the dark background. Data colors are identical between both renders; only chrome flips.

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

Score: 88/100

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

Visual Quality (29/30)

  • VQ-01: Text Legibility (7/8) — Sizes explicitly set (title=12, geom_text=9); all text readable in both themes; both title and labels proportional to the square canvas
  • VQ-02: No Overlap (6/6) — No overlapping text or data elements; START and GOAL labels placed with adequate spacing
  • VQ-03: Element Visibility (6/6) — Maze walls clearly visible at size=0.7; GOAL marker prominent at size=4
  • VQ-04: Color Accessibility (2/2) — High contrast walls (dark on light / light on dark); brand green #009E73 distinguishable on both surfaces
  • VQ-05: Layout & Canvas (4/4) — Maze fills ~65% of 6×6 inch canvas with balanced whitespace; title above with appropriate padding
  • VQ-06: Axis Labels & Title (2/2) — theme_void correctly omits axes; title format correct
  • VQ-07: Palette Compliance (2/2) — Background #FAF8F1 (light) / #1A1A17 (dark); GOAL uses brand green #009E73; text adapts to theme; no pure white/black

Design Excellence (13/20)

  • DE-01: Aesthetic Sophistication (5/8) — Intentional color hierarchy (green GOAL vs. soft-gray START vs. dark walls) elevates this above a plain default; theme_void is the right call for a maze; lacks further sophistication (e.g., no variation in wall weight, no subtle shadow or glow on the goal marker) to reach 6+
  • DE-02: Visual Refinement (4/6) — theme_void removes all unnecessary chrome; consistent wall stroke size; proper background fills; could add subtle entry-gate visual emphasis or slightly varied wall thickness for inner rings
  • DE-03: Data Storytelling (4/6) — Brand green creates a clear focal point at center; soft-gray START guides the eye to the entry; the maze itself creates natural visual tension; no additional storytelling elements (e.g., highlighting the solution path, adding difficulty or ring-count annotations)

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) — Correct circular maze with 7 concentric rings and radial passages
  • SC-02: Required Features (4/4) — Concentric walls ✓, radial passages ✓, entry point on outer perimeter ✓, GOAL at center ✓, DFS guarantees single solution ✓, wall thickness consistent ✓
  • SC-03: Data Mapping (3/3) — Correct polar-to-Cartesian transformation; radii and angles correctly computed; entry gap correctly placed
  • SC-04: Title & Legend (3/3) — Title is "maze-circular · python · plotnine · anyplot.ai" ✓; no legend needed

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) — 7 rings (medium difficulty) with progressively denser sectors per ring; full DFS spanning tree; entry and goal clearly marked
  • DQ-02: Realistic Context (5/5) — Neutral maze puzzle; START/GOAL labels are universally understood; difficulty="medium" is a real-world parameter
  • DQ-03: Appropriate Scale (4/4) — 7 rings within recommended 5–10 range; seed=42 ensures reproducibility; sector counts per ring are well-chosen (1, 6, 12, 18, 24, 30, 36)

Code Quality (9/10)

  • CQ-01: KISS Structure (2/3) — Has helper function that deviates from the flat Imports→Data→Plot→Save pattern; the DFS algorithm is complex enough to partially justify it, but it could be inlined
  • CQ-02: Reproducibility (2/2) — np.random.seed(42) set at top level
  • CQ-03: Clean Imports (2/2) — All imported symbols are used
  • CQ-04: Code Elegance (2/2) — Clean DFS implementation; wall-segment building is logical; no over-engineering; no fake functionality
  • CQ-05: Output & API (1/1) — Saves as plot-{THEME}.png; current plotnine API

Library Mastery (7/10)

  • LM-01: Idiomatic Usage (4/5) — Correct grammar of graphics composition: ggplot() + geom_segment + geom_point + geom_text + coord_fixed + theme_void + labs; coord_fixed ensures square aspect ratio idiomatically
  • LM-02: Distinctive Features (3/5) — Grammar of graphics layering is distinctive to plotnine/ggplot2; coord_fixed for unit-correct circular rendering is a library-specific touch; core wall drawing via geom_segment could be replicated in matplotlib straightforwardly

Score Caps Applied

  • None applied

Strengths

  • Excellent theme adaptation: both renders are correct and all text is readable
  • Perfect spec compliance — all required features present and working
  • Clean minimal design using theme_void correctly for a maze context
  • Intentional color hierarchy: brand green GOAL vs. soft-gray START vs. ink walls
  • Solid DFS maze generation algorithm with guaranteed single solution
  • coord_fixed() used correctly to maintain circular aspect ratio

Weaknesses

  • DE-01 (5/8): Missing aesthetic polish — no variation in wall stroke weight (inner rings could be slightly thinner), no visual emphasis on the entry gate gap, no subtle refinement on the GOAL marker (e.g., concentric rings or glow effect)
  • DE-02 (4/6): Could add entry-gate visual marker (e.g., small arrows or a thicker highlighted arc at the START gap) and a subtle inner-ring fill or color gradient to lead the eye toward the center
  • DE-03 (4/6): No solution-path visualization or color hinting to guide the viewer's eye; difficulty and ring count could be noted in a subtitle or annotation
  • CQ-01 (2/3): function deviates from flat KISS structure

Issues Found

  1. DE-01 MODERATE: Aesthetic sophistication limited by uniform wall treatment
    • Fix: Vary wall stroke weight (e.g., outer ring size=0.9, inner rings taper to 0.5); add a subtle highlight arc or arrow at the entry gap; use a slightly larger goal marker (size=6) with a thin border circle for emphasis
  2. DE-02 MODERATE: Entry gap has no visual marker to draw the eye
    • Fix: Add a small geom_segment or geom_text arrow/chevron at the START gap; or use a filled semi-transparent sector to highlight the entry zone
  3. DE-03 MODERATE: No visual storytelling beyond color assignment
    • Fix: Consider adding a subtitle with difficulty and ring count, or a light translucent path-hint from START toward GOAL using geom_path with low alpha

AI Feedback for Next Attempt

Improve design excellence: (1) Vary wall stroke weight by ring — outer ring thicker (size=1.0), taper inward to size=0.5 — this creates a depth illusion and guides the eye inward; (2) Add a small visual marker at the START gap (e.g., a short inward-pointing arrow or a bold arc segment) to make the entry unmistakably clear; (3) Enlarge the GOAL marker to size=6 and add a thin outer circle (geom_point with hollow fill or a slightly larger geom_point in lighter green behind it) to create a target/bullseye focal point; (4) Keep the KISS structure flat by inlining get_neighbors as a lambda or simply a loop — or accept the function but note it in the AI feedback.

Verdict: REJECTED

@github-actions github-actions Bot added quality:88 Quality score: 88/100 ai-rejected Quality not OK, triggers update labels May 20, 2026
@github-actions github-actions Bot added ai-attempt-1 First repair attempt and removed ai-rejected Quality not OK, triggers update labels May 20, 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
Copy link
Copy Markdown
Contributor

claude Bot commented May 20, 2026

AI Review - Attempt 2/3

Image Description

Light render (plot-light.png): The plot renders on a warm off-white background (~#FAF8F1) with a clean circular maze of 7 concentric rings. Maze walls are rendered in dark ink (#1A1A17) using geom_segment, with visibly tapered stroke weights — outer/mid rings use size=0.9 strokes while inner rings use size=0.45, creating a convincing depth illusion that draws the eye toward the center. A teal GOAL bullseye (#009E73) with a translucent glow halo sits at the center, with "GOAL" text above it in the same green. "START" appears in muted secondary ink (#4A4A44) at the right edge of the outer ring, marking the entry gap. The mandated title "maze-circular · python · plotnine · anyplot.ai" appears in bold dark text at top. A small caption "7 rings · medium" is shown below. All text is clearly readable against the warm light background.

Dark render (plot-dark.png): The same circular maze renders on a warm near-black background (~#1A1A17). Maze walls flip to light/white strokes, maintaining the tapered stroke weight contrast. The GOAL bullseye remains identical #009E73 green — data color is unchanged from the light render, exactly as required. "GOAL" and "START" labels are rendered in light-on-dark text (the theme tokens flip correctly). The title text is clearly visible as light text on the dark surface. The caption at bottom is visible in muted light gray. No dark-on-dark failures detected; all text elements are readable against the near-black background.

Both renders pass the theme-readability checklist.

Score: 91/100

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

Visual Quality (29/30)

  • VQ-01: Text Legibility (7/8) — All font sizes explicitly set (title=12, labels=9, caption=7). Both renders are fully readable. Minor: the caption at size=7 is borderline at mobile widths but acceptable as tertiary metadata.
  • VQ-02: No Overlap (6/6) — No text overlaps with walls or other labels. START, GOAL, caption, and title all occupy distinct regions.
  • VQ-03: Element Visibility (6/6) — Maze walls, entry gap, GOAL bullseye, and START marker are all clearly visible in both themes. Tapered strokes read well.
  • VQ-04: Color Accessibility (2/2) — High contrast walls on both themes; GOAL green (#009E73) is CVD-safe and distinct from the mono wall color.
  • VQ-05: Layout & Canvas (4/4) — 6×6 square canvas is ideal for a circular maze. Maze fills ~70% of the canvas with balanced margins; no clipping.
  • VQ-06: Axis Labels & Title (2/2) — No axis labels needed for this plot type; title format is correct.
  • VQ-07: Palette Compliance (2/2) — GOAL uses #009E73 (Okabe-Ito Add workflow diagram for new prototype discovery #1). Backgrounds are #FAF8F1 / #1A1A17. Chrome tokens flip correctly between themes. Data colors identical between renders.

Design Excellence (15/20)

  • DE-01: Aesthetic Sophistication (6/8) — Well above defaults: intentional tapered stroke weights for depth illusion, GOAL glow halo (alpha=0.18 + solid dot), subtle entry gate arc marking the threshold, and theme-adaptive chrome. Cohesive and purposeful design.
  • DE-02: Visual Refinement (5/6) — theme_void() cleanly strips all chart chrome. Tapered strokes and the multi-layer GOAL marker are polished details. Could push further with slight entrance arrow or path-hint annotation.
  • DE-03: Data Storytelling (4/6) — Clear visual hierarchy: START at outer edge → winding passages → GOAL focal point in brand green at center. The green draws the eye immediately to the objective. Not all aspects of storytelling are present (no solve-path hint, no difficulty annotation beyond caption), but the essential narrative is there.

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) — Correct circular maze with concentric rings and radial passages.
  • SC-02: Required Features (4/4) — Concentric circular walls ✓, radial walls dividing sectors ✓, passages connecting rings ✓, entry on outer edge ✓, goal at center ✓, DFS guarantees exactly one solution ✓, consistent wall thickness ✓, print-friendly mono walls ✓.
  • SC-03: Data Mapping (3/3) — rings, difficulty, and seed parameters all wired correctly. Sector counts scale outward as expected.
  • SC-04: Title & Legend (3/3) — Title is exactly "maze-circular · python · plotnine · anyplot.ai". No legend needed.

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) — Shows all aspects: concentric rings, radial passages, variable sector density per ring, entry gap with gate, goal marker, difficulty caption.
  • DQ-02: Realistic Context (5/5) — Puzzle/game design is a neutral, real-world context. Non-controversial.
  • DQ-03: Appropriate Scale (4/4) — 7 rings at medium difficulty; sector counts ([1,6,12,18,24,30,36,42]) increase appropriately outward; seed=42 for reproducibility.

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3) — Flat linear structure: imports → tokens → params → DFS generation → segment building → plot → save. No functions or classes.
  • CQ-02: Reproducibility (2/2) — np.random.seed(42) set before maze generation.
  • CQ-03: Clean Imports (2/2) — All imports are used; no dead imports.
  • CQ-04: Code Elegance (2/2) — Clean, Pythonic. DFS maze generation is concise with neighbors computed inline. Comments explain non-obvious decisions only.
  • CQ-05: Output & API (1/1) — Saves as plot-{THEME}.png with correct dpi/dimensions.

Library Mastery (7/10)

  • LM-01: Idiomatic Usage (4/5) — Uses plotnine's additive grammar correctly throughout: multiple geom layers, aes() mappings, coord_fixed(), theme_void(), labs(). Slightly below "expert" because the visualization is primarily geometrically hand-crafted.
  • LM-02: Distinctive Features (3/5) — coord_fixed(ratio=1) ensures the circular maze stays circular (not elliptical). Layer composition of geom_segment + geom_point + geom_text is leveraged well. However, the maze rendering is predominantly manual NumPy geometry rather than a plotnine-distinctive pattern.

Score Caps Applied

  • None

Strengths

  • Tapered stroke weights (outer=0.9, inner=0.45) create a genuine depth illusion drawing the eye inward — a deliberate, effective design choice
  • GOAL bullseye with translucent glow halo + solid dot is visually polished and immediately identifies the objective
  • Entry gate arc subtly marks the threshold without heavy-handed labeling
  • DFS maze generation guarantees exactly one solution while remaining fully inline/flat (KISS)
  • Theme adaptation is flawless: wall color, background, text, and INK tokens all flip correctly; GOAL green stays constant

Weaknesses

  • DE-03 could be elevated: consider adding a faint "solve path" highlight or directional arrow near START to guide the viewer's eye immediately into the maze
  • DE-02 minor: the START label could use a small visual accent (dot or arrow) matching the GOAL bullseye treatment to create visual symmetry at both ends of the puzzle
  • Caption "7 rings · medium" at size=7 is at the lower boundary of mobile legibility — bumping to size=8 would be safer

Issues Found

  1. DE-03 MODERATE: Visual storytelling stops at labeling entry/exit — no emphasis on the solving journey or difficulty
    • Fix: Add a faint directional cue near START (e.g., a small arrow pointing inward) or highlight the first passage with a subtle color accent
  2. LM-02 MODERATE: Most rendering is NumPy geometry; plotnine-specific affordances are limited to coord_fixed + layer stacking
    • Fix: No required fix for approval; this is a scoring observation

AI Feedback for Next Attempt

The implementation is strong. If a repair is needed: (1) bump caption font to size=8 for mobile safety, (2) add a small directional marker at the START entry (arrow or accent dot in INK_SOFT) to create visual symmetry with the GOAL bullseye and give viewers an immediate sense of direction, (3) optionally add a faint #009E73 trace for the first few passages from the entry to subtly hint at the solve journey without revealing the solution.

Verdict: APPROVED

@github-actions github-actions Bot added quality:91 Quality score 91/100 ai-approved Quality OK, ready for merge and removed quality:88 Quality score: 88/100 labels May 20, 2026
@MarkusNeusinger MarkusNeusinger merged commit 633200b into main May 20, 2026
3 checks passed
@MarkusNeusinger MarkusNeusinger deleted the implementation/maze-circular/plotnine branch May 20, 2026 08:10
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