Skip to content

feat(seaborn): implement ternary-density#7375

Merged
MarkusNeusinger merged 5 commits into
mainfrom
implementation/ternary-density/seaborn
May 19, 2026
Merged

feat(seaborn): implement ternary-density#7375
MarkusNeusinger merged 5 commits into
mainfrom
implementation/ternary-density/seaborn

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

Implementation: ternary-density - python/seaborn

Implements the python/seaborn version of ternary-density.

File: plots/ternary-density/implementations/python/seaborn.py

Parent Issue: #3696


🤖 impl-generate workflow

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented May 19, 2026

AI Review - Attempt 1/3

Image Description

Light render (plot-light.png): Rendered on a warm off-white background (#FAF8F1). The title "Soil Composition · ternary-density · python · seaborn · anyplot.ai" is in bold dark ink at 24pt and clearly readable. Vertex labels "Clay (%)", "Sand (%)", "Silt (%)" are bold 22pt in dark ink — prominent and well-positioned. Percentage tick labels (20, 40, 60, 80) appear in 14pt muted ink along all three triangle edges — readable but slightly below the 16pt guideline for this canvas size. The colorbar with semantic labels "Low", "Medium", "High" is clearly readable. The viridis density fill shows three distinct density peaks: a high-sand cluster (bright yellow-green) near the bottom-left vertex, a high-clay cluster in the upper-left region, and a high-silt cluster near the bottom-right. Contour lines in Okabe-Ito blue (#0072B2) are visible over the fill. Three families of ternary grid lines (10% intervals) are faintly visible beneath the density layer. All text is readable against the light background — PASS.

Dark render (plot-dark.png): Rendered on a warm near-black background (#1A1A17). Title and vertex labels appear in light cream/off-white ink — clearly readable against the dark surface. Percentage tick labels use INK_SOFT (#B8B7B0) and remain readable — no dark-on-dark failure detected. Colorbar label and semantic tick labels are properly styled in muted light tones. The viridis data colors are identical to the light render — same three density peaks, same positions — confirming data colors did not change between themes. Only the background and chrome elements flipped. Triangle boundary and ternary grid lines adapt correctly. All text readable against the dark background — PASS.

Both renders pass the theme-readability check.

Score: 85/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 5 10
Total 85 100

Visual Quality (29/30)

  • VQ-01: Text Legibility (7/8) — All text readable in both themes; tick labels along ternary edges are 14pt (below 16pt guideline for the 3600×3600 canvas)
  • VQ-02: No Overlap (6/6) — No collisions; percentage labels well-spaced along all three edges
  • VQ-03: Element Visibility (6/6) — Density fill, contour lines, grid, and boundary all clearly visible
  • VQ-04: Color Accessibility (2/2) — viridis is CVD-safe; no red-green as sole signal
  • VQ-05: Layout & Canvas (4/4) — Square 12×12 figsize appropriate for ternary; colorbar well-placed; nothing cut off
  • VQ-06: Axis Labels & Title (2/2) — Vertex labels include units (%); title follows correct descriptive-prefix format
  • VQ-07: Palette Compliance (2/2) — viridis for continuous density data (correct); backgrounds #FAF8F1 / #1A1A17; both renders theme-correct

Design Excellence (11/20)

  • DE-01: Aesthetic Sophistication (5/8) — Above defaults: semantic colorbar labels (Low/Medium/High), clean three-family ternary grid, crisp triangle boundary; three clusters are visible but unlabelled
  • DE-02: Visual Refinement (3/6) — ax.axis('off') for minimal chrome; grid at alpha=0.20; alpha blending on KDE fill (0.85)
  • DE-03: Data Storytelling (3/6) — Three clusters correspond to geological soil types; contour lines add density interpretation; no annotations labelling the clusters to guide the viewer

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) — Correct ternary density plot with KDE heatmap overlay and contour lines
  • SC-02: Required Features (4/4) — viridis colormap, grid lines beneath density layer, vertex labels, contour lines at key density levels — all present
  • SC-03: Data Mapping (3/3) — All three components correctly projected to Cartesian ternary coordinates; sums to 100%
  • SC-04: Title & Legend (3/3) — "Soil Composition · ternary-density · python · seaborn · anyplot.ai" — correct format with descriptive prefix

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) — Shows all aspects: filled density, contour lines, ternary grid, vertex labels, colorbar scale, edge tick marks
  • DQ-02: Realistic Context (5/5) — Soil composition (sand/silt/clay) is a neutral, scientifically grounded geological domain
  • DQ-03: Appropriate Scale (4/4) — 500 samples across three realistic soil-type clusters; values sum to 100%; proportions plausible

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3) — Flat linear script; no functions or classes
  • CQ-02: Reproducibility (2/2) — np.random.seed(42) set
  • CQ-03: Clean Imports (2/2) — All six imports are used
  • CQ-04: Code Elegance (2/2) — Clean coordinate math; proper clip_path usage to confine density to triangle; no fake UI
  • CQ-05: Output & API (1/1) — Saves to plot-{THEME}.png; no bare plot.png

Library Mastery (5/10)

  • LM-01: Idiomatic Usage (3/5) — sns.kdeplot(fill=True, cmap=...) is idiomatic; applying set_clip_path on collections is the correct pattern; sns.set_theme properly initializes the style
  • LM-02: Distinctive Features (2/5) — Only seaborn-specific element is sns.kdeplot; the ternary geometry, grid lines, vertex labels, boundary patch, and tick marks are all pure matplotlib

Score Caps Applied

  • None — no caps triggered

Strengths

  • Correct ternary-to-Cartesian coordinate transformation with three-family grid lines at 10% intervals beneath the density layer
  • Full spec compliance: viridis density fill, multi-level contour lines, clipped to triangle boundary, vertex labels with units
  • Proper theme-adaptive chrome: all text elements use INK/INK_SOFT tokens; both renders pass readability checks
  • Semantic colorbar labels (Low / Medium / High) instead of raw numeric values — excellent interpretation aid
  • Realistic three-cluster soil dataset (sandy, silty, clay-rich) with geologically plausible proportions and 500 samples
  • Clean flat code: linear structure, seed set, all imports used, correct output filenames

Weaknesses

  • Some text sizes below the 16pt guideline: percentage tick labels along ternary edges are 14pt, colorbar tick labels also 14pt — should be 16pt for the 3600×3600 canvas
  • Design excellence is functional but not polished: the three soil clusters (Sandy / Silty / Clay-rich) are unlabelled — annotations would create a clear focal point and guide interpretation
  • Library-specific seaborn features are minimal — the entire ternary geometry, grid, boundary, and labels are matplotlib; only sns.kdeplot is seaborn-specific
  • Contour linewidths=2.0 is slightly thin for the large canvas — 3.0 would improve visibility at full resolution

Issues Found

  1. VQ-01 MINOR: Tick labels at 14pt (spec: 16pt for tick labels on DPI-based libraries)
    • Fix: Change fontsize=14 to fontsize=16 for percentage labels and colorbar tick labels
  2. DE-03 LOW: No annotations identifying the three density clusters
    • Fix: Add ax.text() labels ("Sandy soils", "Silty soils", "Clay-rich soils") positioned at each density peak with an arrow or small offset
  3. LM-02 LOW: Seaborn used only for KDE; all structural elements are matplotlib
    • Fix: This is inherent to ternary plots in seaborn — acceptable limitation; no easy improvement

AI Feedback for Next Attempt

Raise tick label fontsize from 14pt to 16pt across all edge labels and colorbar ticks. Add ax.text() annotations labelling the three density clusters ("Sandy soils", "Silty soils", "Clay-rich soils") to create a clear focal point and narrative. Consider increasing contour linewidths from 2.0 to 3.0 for better visibility at full canvas resolution.

Verdict: APPROVED

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

AI Review - Attempt 2/3

Image Description

Light render (plot-light.png): The plot renders on a warm off-white #FAF8F1 background. The equilateral triangle occupies the central portion of the square canvas, with a thick blue (#0072B2) boundary. The interior is filled with a viridis KDE density heatmap showing three distinct density clusters: a bright yellow-green peak near the bottom-left (sandy soils), a yellow-green peak in the upper-center (clay-rich soils), and a smaller concentration at the bottom-right (silty soils). Blue contour lines overlay the density fill. A viridis colorbar on the right is labeled "Relative Density" with "Low/Medium/High" semantic labels. Vertex labels "Sand (%)", "Silt (%)", "Clay (%)" appear in bold dark text at the three corners. Percentage tick labels (20, 40, 60, 80) run along all three edges. Cluster annotation boxes with rounded corners and off-white fills label each density peak. All text is dark (#1A1A17) and clearly readable against the light background.

Dark render (plot-dark.png): The same composition renders on a warm near-black #1A1A17 background. The viridis density fill and contour lines are identical in color to the light render — data colors have not shifted. The blue triangle boundary is unchanged. Vertex labels, percentage tick labels, colorbar text, and cluster annotations render in light ink (#F0EFE8 / #B8B7B0) against the dark surface. No dark-on-dark failures are present — all text is clearly visible. The colorbar "Relative Density" label and Low/Medium/High tick labels appear in appropriate light tones.

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 15 20
Spec Compliance 15 15
Data Quality 15 15
Code Quality 10 10
Library Mastery 6 10
Total 91 100

Visual Quality (30/30)

  • VQ-01: Text Legibility (8/8) — All font sizes explicitly set: title 24pt, vertex labels 22pt bold, tick labels 16pt, colorbar label 18pt, cluster annotations 15pt; fully readable in both themes
  • VQ-02: No Overlap (6/6) — Vertex labels, edge tick labels, and annotations are well-separated with proper offsets; no collisions
  • VQ-03: Element Visibility (6/6) — Viridis fill at alpha=0.85 provides strong density coverage; contour lines at linewidths=3.0 are prominent; triangle boundary at linewidth=4 anchors the frame
  • VQ-04: Color Accessibility (2/2) — Viridis is perceptually uniform and CVD-safe; no red-green as sole signal
  • VQ-05: Layout & Canvas (4/4) — Square format (3600×3600px) appropriate for symmetric ternary; triangle fills ~75% of canvas with balanced margins for colorbar and vertex labels
  • VQ-06: Axis Labels & Title (2/2) — Vertex labels include units "Sand (%)", "Silt (%)", "Clay (%)"; colorbar labeled "Relative Density"
  • VQ-07: Palette Compliance (2/2) — Viridis used for sequential continuous density data (correct); background #FAF8F1 light / #1A1A17 dark; all chrome tokens correctly theme-adaptive in both renders

Design Excellence (15/20)

  • DE-01: Aesthetic Sophistication (6/8) — Clearly above defaults: cohesive blue structural elements (#0072B2 boundary + contours), semantic colorbar labels, styled annotation boxes with rounded corners and semi-transparent fills; falls just short of publication-ready due to the contour/fill combination feeling slightly mechanical
  • DE-02: Visual Refinement (5/6) — ax.axis('off') removes all spines and ticks; ternary grid at alpha=0.20, linewidth=0.8 is subtle and appropriately transparent beneath the density layer; generous margins; most details polished
  • DE-03: Data Storytelling (4/6) — Three explicitly labeled density peaks guide the viewer to the distinct soil clusters; color contrast between the viridis peaks and dark interior creates visual hierarchy; the viewer immediately identifies the three soil types

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) — Correct ternary diagram with KDE density heatmap overlay; ternary-to-Cartesian transformation correct (Sand → bottom-left, Silt → bottom-right, Clay → top)
  • SC-02: Required Features (4/4) — Perceptually uniform colormap (viridis) ✓; grid lines at 10% intervals beneath density layer at alpha=0.20 ✓; vertex labels with component names ✓; contour lines at key density levels ✓; auto bandwidth selection ✓
  • SC-03: Data Mapping (3/3) — Three components correctly mapped; components sum to 100% enforced by construction; full ternary space represented
  • SC-04: Title & Legend (3/3) — "Soil Composition · ternary-density · python · seaborn · anyplot.ai" matches the required {Descriptive Title} · {spec-id} · {language} · {library} · anyplot.ai format exactly

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) — Shows three distinct density clusters, sparse edge regions, and the full compositional space; KDE with 20 levels reveals fine density gradients
  • DQ-02: Realistic Context (5/5) — Soil texture composition (sand/silt/clay) is a well-established neutral domain in soil science; three clusters correspond to recognizable USDA soil texture classes
  • DQ-03: Appropriate Scale (4/4) — Beta distribution parameters produce plausible soil percentage ranges; components sum to 100% exactly; cluster positions (bottom-left sandy, bottom-right silty, top clay-rich) correctly reflect ternary diagram conventions

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3) — Linear flow: imports → tokens → data generation → ternary transform → plot (grid, KDE fill, KDE contours, boundary, colorbar, labels, annotations, style) → save; no classes or functions
  • CQ-02: Reproducibility (2/2) — np.random.seed(42) set before data generation
  • CQ-03: Clean Imports (2/2) — All 7 imports are used: os, matplotlib.cm, matplotlib.pyplot, numpy, seaborn, matplotlib.colors.Normalize, matplotlib.patches.Polygon
  • CQ-04: Code Elegance (2/2) — Clean Pythonic code; the two-pass clip loop is a justified pattern for seaborn/matplotlib KDE clipping; no over-engineering
  • CQ-05: Output & API (1/1) — Saves as plot-{THEME}.png with dpi=300, bbox_inches='tight', facecolor=PAGE_BG; uses current seaborn 0.13.2 API

Library Mastery (6/10)

  • LM-01: Idiomatic Usage (3/5) — sns.kdeplot with fill=True, cmap='viridis', levels=20, thresh=0.02 is idiomatic seaborn; dual-call pattern (fill pass + contour pass) is the seaborn-recommended approach; sns.set_theme() with RC params is correct — but the majority of the geometric work (triangle, grid, vertex labels, colorbar) is pure matplotlib, necessary given seaborn's lack of native ternary support
  • LM-02: Distinctive Features (3/5) — The thresh=0.02 parameter to clip near-zero density regions and levels=20 for smooth fills are seaborn-specific; using sns.kdeplot on custom Cartesian-transformed ternary coordinates is a creative application of the library's KDE engine

Score Caps Applied

  • None — all caps avoided (DE-01=6 > 2, VQ-02=6, VQ-03=6, SC-01=5, DQ-02=5, CQ-04=2)

Strengths

  • Perfect spec compliance: all required features (viridis fill, grid at 10% intervals, contour lines, labeled vertices, auto bandwidth) are correctly implemented
  • Dual-call sns.kdeplot pattern (fill + contours) with correct triangle clip path produces a clean, well-layered density visualization
  • Full theme-adaptive chrome: background, vertex labels, tick labels, colorbar, and annotation boxes all correctly flip between light and dark themes
  • Soil composition domain is realistic, neutral, and scientifically appropriate with correctly-constrained ternary data (sums to 100%)
  • Cluster annotations with labeled density peaks elevate data storytelling above mere display

Weaknesses

  • LM-01 ceiling: seaborn's contribution is limited to the KDE engine — the triangle geometry, grid, labels, and colorbar are all matplotlib; unavoidable for ternary plots but caps library mastery
  • DE-01 has room for growth: the blue boundary/contour color is functional but the overall aesthetic could achieve publication-ready polish with more intentional typography sizing ratios or a finer grid opacity

Issues Found

  1. LM-01 LIMITED: seaborn's role is confined to kdeplot calls; all geometry is matplotlib — acceptable but limits mastery ceiling
    • Note: This is inherent to the plot type, not a fixable code issue

AI Feedback for Next Attempt

Implementation is strong and approved. If regenerated: consider using sns.kdeplot with bw_adjust explicitly documented, and explore whether sns.set_context("talk") could unify font scaling more idiomatically rather than setting each element size manually.

Verdict: APPROVED

@github-actions github-actions Bot added quality:91 Quality score 91/100 ai-approved Quality OK, ready for merge and removed quality:85 Quality score 85/100 labels May 19, 2026
@MarkusNeusinger MarkusNeusinger merged commit d63cc98 into main May 19, 2026
@MarkusNeusinger MarkusNeusinger deleted the implementation/ternary-density/seaborn branch May 19, 2026 10:47
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