Skip to content

feat(plotnine): implement swarm-basic - #9938

Merged
MarkusNeusinger merged 6 commits into
mainfrom
implementation/swarm-basic/plotnine
Jul 26, 2026
Merged

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

Conversation

@github-actions

Copy link
Copy Markdown
Contributor

Implementation: swarm-basic - python/plotnine

Implements the python/plotnine version of swarm-basic.

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

Parent Issue: #974


🤖 impl-generate workflow

github-actions Bot added 2 commits July 26, 2026 07:07
Regen from quality 87. Addressed:
- Canvas: figure_size/dpi were historical (16x9 @ dpi=300 -> wrong
  4800x2700 output); reset to canonical figure_size=(8, 4.5), dpi=400,
  width/height in ggsave per prompts/library/plotnine.md, confirmed
  3200x1800 output.
- Replaced position_jitter (random scatter, caused visible overlap in
  the 55-pt Medium Dose group) with a deterministic beeswarm packing
  algorithm: bins each group's values and alternates left/right stacking
  within a bin, producing a true lens-shaped swarm with no randomness
  needed for reproducibility.
- Design excellence: explicit panel_border=element_blank() and
  axis_ticks_major=element_blank() instead of relying implicitly on
  theme_minimal() defaults.
- Library mastery / storytelling: added a real dashed median-to-median
  trend line (geom_line + geom_point diamond on a summarized medians_df)
  to make the dose-response trend explicit — a genuine distinctive
  plotnine feature beyond the single stat_summary layer.
- Font sizes rescaled to the new dpi=400/figsize=(8,4.5) canvas per the
  library prompt's sizing table (title 13pt, axis titles 10pt, tick
  labels 8pt) — the old 24/20/16pt values were tuned for the historical
  oversized canvas.
- Kept: Imprint palette (already migrated, first series #009E73),
  theme-adaptive chrome, clinical dose-response data scenario,
  np.random.seed(42) reproducibility, hidden legend.
@claude

claude Bot commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

AI Review - Attempt 1/3

Image Description

Light render (plot-light.png): Warm off-white background (#FAF8F1). Title "swarm-basic · plotnine · anyplot.ai" is centered at the top, fully within canvas bounds, dark ink, comfortably sized. X-axis reads "Treatment Group" with four category labels (Placebo, Low Dose, Medium Dose, High Dose); Y-axis reads "Biomarker Level (ng/mL)" with numeric ticks. Grid lines are faint horizontal guides. Four beeswarm columns are shown, colored green/purple/blue/amber (Imprint order, Placebo = #009E73), each with individual data points, a black diamond median marker, and a dashed grey line connecting the medians left-to-right to trace the dose-response trend. All title/axis/tick text is clearly readable against the light background.

Dark render (plot-dark.png): Warm near-black background (#1A1A17). Same layout and text content, now rendered in light ink/light grey — fully legible, no dark-on-dark issues found. Data colors (green/purple/blue/amber) are identical to the light render — only chrome flipped. The median diamond markers flip from black to off-white and the trend line becomes lighter grey so both remain visible against the dark panel.

Both renders are readable with no legibility failures in either theme.

Score: 87/100

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

Visual Quality (27/30)

  • VQ-01: Text Legibility (7/8)
  • VQ-02: No Overlap (6/6)
  • VQ-03: Element Visibility (4/6) - points overlap/stack near-concentrically in the two densest groups
  • VQ-04: Color Accessibility (2/2)
  • VQ-05: Layout & Canvas (4/4)
  • VQ-06: Axis Labels & Title (2/2)
  • VQ-07: Palette Compliance (2/2)

Design Excellence (16/20)

  • DE-01: Aesthetic Sophistication (6/8) - Custom palette, intentional hierarchy via median markers + trend line, above defaults
  • DE-02: Visual Refinement (5/6) - Subtle grid, spines/ticks removed, generous whitespace
  • DE-03: Data Storytelling (5/6) - Dashed median-trend line creates a clear focal point showing the dose-response relationship

Spec Compliance (14/15)

  • SC-01: Plot Type (5/5)
  • SC-02: Required Features (3/4) - all features present, but spec's "without excessive overlap" note only partially met
  • SC-03: Data Mapping (3/3)
  • SC-04: Title & Legend (3/3)

Data Quality (14/15)

  • DQ-01: Feature Coverage (5/6) - varying spread/mean per group plus a genuine low outlier in Low Dose
  • DQ-02: Realistic Context (5/5)
  • DQ-03: Appropriate Scale (4/4)

Code Quality (9/10)

  • CQ-01: KISS Structure (2/3) - helper function beeswarm_offsets() needed since plotnine has no native swarm geom, but deviates from strict Imports→Data→Plot→Save
  • CQ-02: Reproducibility (2/2)
  • CQ-03: Clean Imports (2/2)
  • CQ-04: Code Elegance (2/2)
  • CQ-05: Output & API (1/1)

Library Mastery (7/10)

  • LM-01: Idiomatic Usage (4/5) - Idiomatic ggplot/plotnine layering (geom_point + geom_line + geom_point), scale_color_manual, theme()
  • LM-02: Distinctive Features (3/5) - Layered grammar-of-graphics composition is somewhat plotnine-flavored, but the swarm-packing logic itself is generic pandas/numpy

Score Caps Applied

  • None

Strengths

  • Deterministic custom beeswarm-packing algorithm (bin + alternate offsets) gives reproducible, collision-aware point placement instead of random jitter
  • Median diamond markers connected by a dashed trend line make the dose-response relationship immediately visible — strong data storytelling for an ordered categorical axis
  • Full theme-adaptive chrome: median markers, connecting line, grid, and text all correctly re-derive from INK/INK_SOFT/PAGE_BG tokens so both renders are legible
  • Correct Imprint categorical palette in canonical order with Placebo mapped to #009E73
  • Realistic clinical-trial biomarker scenario with decreasing variance at higher doses — biologically plausible and includes a genuine low outlier in the Low Dose group

Weaknesses

  • Points visibly overlap/stack in the two densest groups (Medium Dose n=55, High Dose n=40) — the fixed bin/spacing offsets produce two tight columns where several circles sit almost concentrically instead of spreading outward; tighten n_bins or reduce point size/spacing so the swarm avoids excessive overlap as the spec's notes require
  • beeswarm_offsets() introduces a helper function, breaking the KISS Imports→Data→Plot→Save structure — acceptable given plotnine has no native swarm geom, but consider inlining or simplifying if the offset logic can be shortened
  • The custom offset/median-line logic is generic pandas/numpy rather than a plotnine-distinctive feature — LM-02 stays low; consider layering a subtle geom_violin or density hint behind the points to lean further into plotnine's grammar-of-graphics strengths

Issues Found

  1. VQ-03 / SC-02 MEDIUM: Points overlap near-concentrically in the Medium Dose and High Dose columns
    • Fix: increase n_bins in beeswarm_offsets() (or reduce geom_point(size=...)) so points in dense groups spread further apart instead of stacking
  2. CQ-01 / LM-02 LOW: Swarm layout logic is a generic helper function rather than a plotnine-idiomatic technique
    • Fix: keep the helper (necessary given plotnine's lack of a native swarm geom) but consider simplifying it or pairing it with a plotnine-native layer (e.g. a subtle violin outline) to better showcase the library's grammar-of-graphics strengths

AI Feedback for Next Attempt

Tighten the beeswarm packing so points in the denser Medium/High Dose groups spread outward instead of overlapping/stacking — increase n_bins or reduce point size slightly. Everything else (palette, theme-adaptive chrome, median/trend-line storytelling, spec compliance, data realism) is strong and should be preserved.

Verdict: REJECTED

@github-actions github-actions Bot added quality:87 Quality score 87/100 ai-rejected Quality not OK, triggers update labels Jul 26, 2026
@github-actions github-actions Bot added ai-attempt-1 First repair attempt and removed ai-rejected Quality not OK, triggers update labels Jul 26, 2026
Attempt 1/4 - 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 Jul 26, 2026

Copy link
Copy Markdown
Contributor

AI Review - Attempt 2/3

Image Description

Light render (plot-light.png): Warm off-white background (#FAF8F1). Title "swarm-basic · plotnine · anyplot.ai" is centered at the top, fully within canvas bounds, dark ink, comfortably sized. X-axis reads "Treatment Group" with four category labels (Placebo, Low Dose, Medium Dose, High Dose); Y-axis reads "Biomarker Level (ng/mL)" with numeric ticks. Grid lines are faint. Four beeswarm columns are shown, colored green/purple/blue/amber (Imprint canonical order, Placebo = #009E73), each with individual data points, a black diamond median marker, and a dashed grey line connecting the medians left-to-right to trace the dose-response trend. Zoomed inspection of the densest columns (Medium Dose n=55, High Dose n=40) confirms the point-overlap problem from attempt 1 is fully resolved — points are cleanly separated in a radially symmetric ring pattern. All title/axis/tick text is clearly readable against the light background.

Dark render (plot-dark.png): Warm near-black background (#1A1A17). Same layout and text content, rendered in light ink/light grey — fully legible, no dark-on-dark issues found. Data colors (green/purple/blue/amber) are identical to the light render — only chrome flipped. The median diamond markers flip from black to off-white and the trend line becomes lighter grey, both remain clearly visible. Zoomed inspection confirms the same overlap-free point separation as the light render.

Both renders are readable with no legibility failures in either theme.

Score: 89/100

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

Visual Quality (29/30)

  • VQ-01: Text Legibility (8/8)
  • VQ-02: No Overlap (6/6)
  • VQ-03: Element Visibility (5/6) - point overlap from attempt 1 is fully resolved, but the new deterministic slot packing produces a quantized ring pattern rather than an optimally organic density-following spread
  • VQ-04: Color Accessibility (2/2)
  • VQ-05: Layout & Canvas (4/4)
  • VQ-06: Axis Labels & Title (2/2)
  • VQ-07: Palette Compliance (2/2)

Design Excellence (15/20)

  • DE-01: Aesthetic Sophistication (5/8) - Custom palette and intentional median/trend hierarchy above defaults, but the mechanical radial "starburst" point pattern reads as an algorithmic artifact rather than elegant/organic
  • DE-02: Visual Refinement (5/6) - Subtle grid, spines/ticks removed, generous whitespace
  • DE-03: Data Storytelling (5/6) - Dashed median-trend line remains a clear focal point showing the dose-response relationship

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5)
  • SC-02: Required Features (4/4) - overlap-avoidance requirement now satisfied after the packing rewrite
  • SC-03: Data Mapping (3/3)
  • SC-04: Title & Legend (3/3)

Data Quality (14/15)

  • DQ-01: Feature Coverage (5/6) - varying spread/mean per group plus a genuine low outlier in Low Dose
  • DQ-02: Realistic Context (5/5)
  • DQ-03: Appropriate Scale (4/4)

Code Quality (9/10)

  • CQ-01: KISS Structure (2/3) - helper function beeswarm_offsets() needed since plotnine has no native swarm geom, deviates from strict Imports→Data→Plot→Save
  • CQ-02: Reproducibility (2/2)
  • CQ-03: Clean Imports (2/2)
  • CQ-04: Code Elegance (2/2)
  • CQ-05: Output & API (1/1)

Library Mastery (7/10)

  • LM-01: Idiomatic Usage (4/5) - Idiomatic ggplot/plotnine layering (geom_point + geom_line + geom_point), scale_color_manual, theme()
  • LM-02: Distinctive Features (3/5) - Layered grammar-of-graphics composition is plotnine-flavored, but the swarm-packing logic itself remains generic pandas/numpy

Score Caps Applied

  • None

Strengths

  • Overlap fully resolved: the rewritten deterministic slot-based beeswarm packing (ascending-value sweep with min-gap-gated alternating offsets) eliminates the near-concentric point stacking flagged in attempt 1, even in the densest Medium Dose (n=55) and High Dose (n=40) columns
  • Median diamond markers connected by a dashed trend line remain a strong, clear focal point that makes the dose-response relationship immediately visible
  • Full theme-adaptive chrome preserved: median markers, trend line, grid, and text all correctly re-derive from INK/INK_SOFT/PAGE_BG tokens, so both renders are legible with no dark-on-dark or light-on-light failures
  • Correct Imprint categorical palette in canonical order with Placebo mapped to #009E73, identical data colors across both renders
  • Realistic clinical-trial biomarker scenario with decreasing variance at higher doses and a genuine low outlier in Low Dose — biologically plausible and appropriately scaled

Weaknesses

  • The new packing algorithm swaps the overlap problem for a different visual artifact: points in the denser groups (especially Medium Dose and High Dose) form a rigid, radially-symmetric "starburst"/concentric-ring pattern instead of an organic beeswarm silhouette — reads as a mechanical, quantized grid rather than a natural density-following spread. Consider adding a small random jitter within each slot, or a finer/variable spacing step, to break the perfect radial symmetry while keeping points non-overlapping
  • beeswarm_offsets() is still a helper function, a necessary but acknowledged deviation from strict KISS structure (unavoidable since plotnine has no native swarm geom)
  • The swarm-packing logic itself remains generic pandas/numpy rather than a plotnine-distinctive technique — LM-02 stays low

Issues Found

  1. DE-01 LOW-MEDIUM: Deterministic ring/starburst point pattern reads as mechanical rather than organic
    • Fix: introduce a small amount of randomized jitter within each offset slot (seeded, so it stays reproducible) or vary the spacing step slightly so the swarm silhouette looks more density-driven and less like a perfect radial grid
  2. LM-02 LOW: Swarm layout logic is generic pandas/numpy rather than a plotnine-idiomatic technique
    • Fix: keep the helper (necessary given plotnine's lack of a native swarm geom) but consider pairing it with a subtle plotnine-native layer (e.g. a faint violin outline or density hint) to lean further into the library's grammar-of-graphics strengths

AI Feedback for Next Attempt

Overlap is now fixed — great work. The remaining polish item is purely aesthetic: the ring/starburst packing pattern looks mechanical rather than organic. If further repair passes happen, consider adding subtle jitter to break the radial symmetry. Everything else (palette, theme-adaptive chrome, median/trend-line storytelling, spec compliance, data realism) is strong and should be preserved.

Verdict: APPROVED

@github-actions github-actions Bot added quality:89 Quality score 89/100 ai-approved Quality OK, ready for merge and removed quality:87 Quality score 87/100 labels Jul 26, 2026
@MarkusNeusinger
MarkusNeusinger merged commit a243786 into main Jul 26, 2026
5 checks passed
@MarkusNeusinger
MarkusNeusinger deleted the implementation/swarm-basic/plotnine branch July 26, 2026 07:26
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:89 Quality score 89/100

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant