Skip to content

feat(seaborn): implement network-force-directed#9579

Merged
MarkusNeusinger merged 6 commits into
mainfrom
implementation/network-force-directed/seaborn
Jul 1, 2026
Merged

feat(seaborn): implement network-force-directed#9579
MarkusNeusinger merged 6 commits into
mainfrom
implementation/network-force-directed/seaborn

Conversation

@github-actions

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

Copy link
Copy Markdown
Contributor

Implementation: network-force-directed - python/seaborn

Implements the python/seaborn version of network-force-directed.

File: plots/network-force-directed/implementations/python/seaborn.py

Parent Issue: #990


🤖 impl-generate workflow

github-actions Bot added 2 commits July 1, 2026 01:17
Regen from quality 86. Addressed:
- Canvas: figsize=(16,9) dpi=300 → figsize=(8,4.5) dpi=400 (3200×1800 hard contract)
- Removed forbidden bbox_inches="tight" from savefig; use subplots_adjust instead
- Added missing "python" language token to title format
- Rescaled all font sizes to match 3200×1800 canvas (title 12pt, labels 10pt, legend 8pt)
- Adjusted node sizes and edge widths for the correct canvas
- Fixed "Okabe-Ito" comment to "Imprint palette"
@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 (#FAF8F1) background — correct surface. Title "network-force-directed · python · seaborn · anyplot.ai" at 12pt dark ink is fully readable. Axis labels "Force-directed X" / "Force-directed Y" at 10pt are readable; tick values suppressed (appropriate for force-directed coordinates). 37 nodes rendered in three Imprint palette colors: Engineering=green (#009E73, 15 nodes), Marketing=purple (#C475FD, 12 nodes), Sales=blue (#4467A3, 10 nodes). Node sizes scale visibly by degree (hub nodes large, peripheral nodes small). Bridge nodes carry ink-colored open-ring overlays. Edges shown as thin gray lines with transparency (alpha=0.22) and weight-proportional widths. Hub node text annotations ("Node 0", "Node 1", etc.) visible in dark INK_SOFT at 7pt. Stats summary "Nodes: 37 · Edges: 98 · Avg degree: 5.3 · Bridges: 26" embedded at bottom-center. Legend upper-left: Department title + four entries. All text is readable against the light background. Notable issue: hub annotations in the dense center cluster (Node 0, 1, 3, 6, 7, 8, 9, 12) significantly overlap with each other and with node markers.

Dark render (plot-dark.png): Warm near-black (#1A1A17) background — correct surface. Title and axis labels rendered in light ink (#F0EFE8) — clearly readable against the dark background. No dark-on-dark failures: all chrome elements correctly flip to light tones. Legend background uses ELEVATED_BG (#242420) with light ink text. Stats summary visible in INK_MUTED light tone. Imprint data colors are identical to the light render (green, purple, blue unchanged — only chrome flips). Hub node annotations in INK_SOFT light tone are readable. Both renders pass theme readability checks.

Score: 82/100

Category Score Max
Visual Quality 24 30
Design Excellence 13 20
Spec Compliance 15 15
Data Quality 15 15
Code Quality 10 10
Library Mastery 5 10
Total 82 100

Visual Quality (24/30)

  • VQ-01: Text Legibility (6/8) — All sizes explicitly set (title=12pt, axis=10pt, legend=8pt, hub labels=7pt). Both themes readable. Deduction: hub annotation density in center cluster creates legibility clutter.
  • VQ-02: No Overlap (3/6) — Multiple hub annotations (Node 0, 1, 3, 6, 7, 8, 9, 12) cluster in center-upper area with significant text-on-text and text-on-node overlap.
  • VQ-03: Element Visibility (6/6) — Node size range (80–400 by degree) well-adapted to 37-node network. Edges (alpha=0.22) visible but non-dominant. Bridge rings clearly distinguishable.
  • VQ-04: Color Accessibility (2/2) — Imprint palette is CVD-safe across three distinct hue families (green/purple/blue). Node size adds redundant encoding for degree.
  • VQ-05: Layout & Canvas (3/4) — Good overall layout. Minor: isolated Sales nodes drift to lower-left, leaving some natural whitespace in that quadrant.
  • VQ-06: Axis Labels & Title (2/2) — "Force-directed X/Y" appropriate for coordinate system. No ticks (correct for relative force-layout positions). Title format correct.
  • VQ-07: Palette Compliance (2/2) — Engineering=#009E73 as first series. Multi-series in canonical Imprint order. Light bg=#FAF8F1, dark bg=#1A1A17. Chrome correctly flips. Data colors theme-invariant.

Design Excellence (13/20)

  • DE-01: Aesthetic Sophistication (5/8) — Above defaults: triple encoding (color=community, size=degree, ring=bridge), node PAGE_BG edges for definition, semi-transparent edges. Intentional visual hierarchy. Not quite FiveThirtyEight-level polish — bridge-ring overlay and stats annotation are thoughtful additions.
  • DE-02: Visual Refinement (4/6) — Top/right spines removed. No grid (correct choice for force-directed). Edge transparency tasteful. Node white-edges add separation. Stats text cleanly embedded. Several refinement choices made above defaults.
  • DE-03: Data Storytelling (4/6) — Clear hierarchy: community colors cluster spatially, degree-scaled hub nodes dominate the view, bridge rings highlight inter-community connectors, stats annotation quantifies the network. Viewer immediately reads community structure and hub influence.

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) — Correct force-directed graph with Fruchterman-Reingold physics implemented inline (150 iterations).
  • SC-02: Required Features (4/4) — Node degree sizing, edge weight line widths, sufficient FR iterations, hub-only labeling, community structure all present.
  • SC-03: Data Mapping (3/3) — Force-directed positions correctly derived. All 37 nodes and 98 edges visible.
  • SC-04: Title & Legend (3/3) — Title: "network-force-directed · python · seaborn · anyplot.ai". Legend: Engineering (15), Marketing (12), Sales (10), Bridge node.

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) — Community structure, hub nodes, bridge nodes, degree variation, weighted edges all demonstrated.
  • DQ-02: Realistic Context (5/5) — Organizational social network with Engineering/Marketing/Sales departments. Neutral business context.
  • DQ-03: Appropriate Scale (4/4) — 37 nodes (spec range 20–200). Intra-community edge prob 35%, inter-community 5% — realistic social network densities.

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3) — Linear: imports → theme → data → FR layout → plot → save. No functions/classes.
  • CQ-02: Reproducibility (2/2) — np.random.seed(42) set.
  • CQ-03: Clean Imports (2/2) — os, matplotlib.pyplot, numpy, seaborn — all used.
  • CQ-04: Code Elegance (2/2) — Clean Pythonic code. FR algorithm inline is appropriate complexity. No fake UI.
  • CQ-05: Output & API (1/1) — Saves as plot-{THEME}.png. No bbox_inches='tight'. Current seaborn API.

Library Mastery (5/10)

  • LM-01: Idiomatic Usage (3/5) — sns.scatterplot(hue=, size=, sizes=, palette=, edgecolor=, legend=False) is idiomatic seaborn. Theme via sns.set_theme(rc={...}) is correct pattern. However, FR layout, edge drawing, bridge rings, node annotation, and legend handles are all raw matplotlib — seaborn contributes only the node scatter layer.
  • LM-02: Distinctive Features (2/5) — Uses seaborn's hue+size+sizes triple-parameter combination for simultaneous community+degree encoding (a distinctive seaborn pattern). But core network rendering is library-agnostic matplotlib. Seaborn's sizes=(min, max) range rescaling is the most distinctively seaborn element used.

Score Caps Applied

  • None — no caps triggered (VQ-02=3 not 0; DE-01=5, DE-02=4 both above ≤2 threshold)

Strengths

  • Perfect Imprint palette compliance: Engineering=#009E73, Marketing=#C475FD, Sales=#4467A3 in canonical order with correct theme-adaptive backgrounds in both renders
  • Excellent spec compliance — FR algorithm inline, degree-scaled nodes, edge weight widths, bridge node ring highlights, and hub-only labels all per spec
  • Realistic organizational social network scenario with plausible intra/inter-community edge densities (35%/5%)
  • Clean code: KISS structure, np.random.seed(42), all sizes explicitly set, no classes or functions
  • Good visual refinement: top/right spines removed, no grid appropriate for network, transparent edges, node white-edge styling

Weaknesses

  • Hub node label overlap: Too many hub annotations in the dense center cluster (Node 0, 1, 3, 6, 7, 8, 9, 12 all labeled) — their text overlaps significantly. Filter to only the top 3–5 hubs by degree, or use a minimum-distance filter to suppress labels when two annotated nodes are too close in plot-space.
  • Library Mastery limited: seaborn contributes only the sns.scatterplot node layer; edges, bridge rings, legend handles, and annotations are all raw matplotlib. Consider using seaborn more distinctively, e.g. sns.scatterplot with style= parameter for bridge-node shape encoding alongside hue+size.
  • Lower-left canvas whitespace: Isolated Sales (blue) nodes drift far from the main cluster, leaving the lower-left quadrant mostly empty — consider tuning the FR spring constant k or normalisation to keep peripheral nodes closer to the cluster centroid.
  • Hub label fontsize=7 is at the minimum readable threshold for mobile viewports; prefer fontsize=8 for hub annotations.

Issues Found

  1. VQ-02 MODERATE: Hub node annotations cluster and overlap in the central high-degree region
    • Fix: Limit labels to top 3–5 nodes by degree (e.g. degree_threshold = np.percentile(degrees, 87) instead of 75) or add a spatial deduplication step that skips labeling a node if a previously labeled node is within distance < 0.15 in normalized plot space.
  2. LM-02 LOW: seaborn's distinctive features underutilized beyond basic hue+size scatterplot
    • Fix: Add style=is_bridge parameter to sns.scatterplot so bridge nodes use a different marker shape — this uses seaborn's three-way encoding (hue+size+style) which is more distinctively seaborn.

AI Feedback for Next Attempt

Two targeted improvements needed: (1) Reduce label density — raise the hub-label degree threshold from the 75th percentile to ~87th percentile or add a distance-based spatial filter so labels only appear when no other labeled node is within 0.15 normalized-coordinate units. (2) Leverage seaborn's style parameter — pass style=[1 if i in bridge_nodes else 0 for i in range(n)] and markers={0: 'o', 1: 'D'} to sns.scatterplot for bridge nodes, then remove or simplify the manual ax.scatter bridge ring overlay. This improves LM-02 by using a distinctively seaborn three-way encoding (hue+size+style). These are the two changes that will push the score above 90.

Verdict: REJECTED

@github-actions github-actions Bot added quality:82 Quality score 82/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
@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): The plot renders on a warm off-white (#FAF8F1) background with 37 nodes spread across a force-directed layout revealing three communities. Engineering nodes (#009E73 green) form a dense central-left cluster with the largest nodes (high-degree hubs), Marketing (#C475FD purple) occupies the right side, and Sales (#4467A3 blue) is sparse at the bottom-left. Bridge nodes appear as diamond markers in all three community colors. Edges are drawn as thin grey lines with alpha=0.22 and thickness varying by weight. Hub labels "Node 3", "Node 1", "Node 4", "Node 9" annotate the top-degree nodes at 8pt. A legend in the upper left shows department colors with counts and a bridge-node diamond indicator. Network stats ("Nodes: 37 · Edges: 98 · Avg degree: 5.3 · Bridges: 26") appear at the bottom center in muted ink. Title in dark text at top. All text is clearly readable against the light background — no "light on light" failures.

Dark render (plot-dark.png): The same plot on the warm near-black (#1A1A17) surface. Title and all axis labels switch to light cream (#F0EFE8), ticks and spines to INK_SOFT light-grey (#B8B7B0), legend box to elevated dark (#242420). Data colors are identical to the light render — Engineering green, Marketing purple, Sales blue are all unchanged. Edge lines are now light-grey against the dark background. Hub node labels are visible in light-grey. Stats line in muted light text. No dark-on-dark failures detected — all chrome successfully adapts to the dark surface. Brand green #009E73 reads clearly on the near-black background.

Both paragraphs required. Both renders pass legibility checks.

Score: 88/100

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

Visual Quality (29/30)

  • VQ-01: Text Legibility (7/8) — All font sizes explicitly set (title=12, axes=10, annotations=8, legend=8/9, stats=7). Readable in both themes. Minor: stats at 7pt may be marginal at 400px mobile; hub labels close in central cluster but non-overlapping.
  • VQ-02: No Overlap (6/6) — No overlap detected. Hub labels in the Engineering cluster are close but all remain readable and separated.
  • VQ-03: Element Visibility (6/6) — 37 nodes with sizes 80–400 by degree clearly visible. Edge alpha=0.22 keeps the graph readable. Circle/diamond shapes clearly distinguishable.
  • VQ-04: Color Accessibility (2/2) — Imprint green/purple/blue are perceptually distinct and CVD-safe. Redundant shape encoding (circle/diamond) adds accessibility.
  • VQ-05: Layout & Canvas (4/4) — Plot fills ~70% of canvas, balanced margins via subplots_adjust. Legend and stats well-positioned.
  • VQ-06: Axis Labels & Title (2/2) — "Force-directed X" and "Force-directed Y" are descriptive and appropriate for network coordinates.
  • VQ-07: Palette Compliance (2/2) — Imprint canonical order: Engineering=#009E73, Marketing=#C475FD, Sales=#4467A3. Backgrounds #FAF8F1/#1A1A17. Data colors identical across both renders. Full theme-adaptive chrome.

Design Excellence (13/20)

  • DE-01: Aesthetic Sophistication (5/8) — Above a configured default: custom FD layout, triple encoding, selective hub labeling, edge-weight thickness, themed chrome. Not publication-ready — uniform grey edges and no standout focal point hold it back from 6+.
  • DE-02: Visual Refinement (4/6) — Good: top/right spines removed, all ticks removed (appropriate for network coords), subtle edge alpha, no grid, clean whitespace. Not quite "every detail polished" — edge styling is uniform and doesn't differentiate within vs cross-community connections.
  • DE-03: Data Storytelling (4/6) — Good visual hierarchy: large green Engineering cluster dominates, bridge diamonds mark connectors, hub labels identify key nodes, stats provide context. Falls short of 6/6 — no explicit technique (e.g., highlighted bridge paths) makes one key insight unmissable.

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) — Correct force-directed graph with custom Fruchterman-Reingold simulation (150 iterations).
  • SC-02: Required Features (4/4) — All spec features: nodes with IDs, 98 edges, node size by degree, edge thickness by weight, 3-community structure, bridge node identification.
  • SC-03: Data Mapping (3/3) — All 37 nodes and 98 edges plotted; force-directed X/Y layout correct.
  • SC-04: Title & Legend (3/3) — Title format correct. Legend: Engineering (15), Marketing (12), Sales (10), Bridge node.

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) — 3 communities, within-community dense edges (p=0.35) vs sparse cross-community (p=0.05), weighted edges, degree-varying sizes, bridge nodes.
  • DQ-02: Realistic Context (5/5) — Organizational social network, real departments (Engineering/Marketing/Sales), neutral business scenario.
  • DQ-03: Appropriate Scale (4/4) — 37 nodes (within 20–200 spec range), 98 edges, avg degree 5.3. Stochastic block model probabilities are realistic.

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3) — Linear structure, no functions or classes.
  • CQ-02: Reproducibility (2/2) — np.random.seed(42).
  • CQ-03: Clean Imports (2/2) — os, matplotlib.pyplot, numpy, pandas, seaborn — all used.
  • CQ-04: Code Elegance (2/2) — Clean and well-organized. Inline FD algorithm is necessarily verbose but correctly structured. No fake UI elements.
  • CQ-05: Output & API (1/1) — Saves as plot-{THEME}.png at dpi=400, no bbox_inches='tight', current API.

Library Mastery (6/10)

  • LM-01: Idiomatic Usage (3/5) — Uses sns.scatterplot with multi-encoding (hue+size+style, palette dict, sizes range, style_order) idiomatically. Legend constructed manually via matplotlib scatter handles rather than seaborn's built-in legend — less idiomatic; most visualization work (edges, annotations, layout) is matplotlib-level.
  • LM-02: Distinctive Features (3/5) — Seaborn's three-way encoding in a single scatterplot call (hue + size + style with palette dict and sizes range) is distinctively seaborn — the same in pure matplotlib requires 3× more code. A genuine showcase of seaborn's declarative multi-encoding strength.

Score Caps Applied

  • None — all caps checked: VQ-02>0, VQ-03>0, SC-01>0, DQ-02>0, DE-01=5>2 so no "boring cap", CQ-04>0.

Strengths

  • Custom Fruchterman-Reingold layout (150 iterations) implemented inline — realistic organic community structure
  • Three-way seaborn encoding (hue=department, size=degree, style=node_type) in a single scatterplot call
  • Imprint palette in canonical order with full theme-adaptive chrome (6+ tokens) — both renders pass
  • Edge weight encoded in line thickness (0.5 + weight × 1.0) + alpha=0.22 keeps graph uncluttered
  • Selective hub labeling (top-4 only) and network stats annotation add informational value without visual noise
  • All font sizes explicitly set throughout; no bbox_inches='tight'; clean KISS structure

Weaknesses

  • Stats annotation at fontsize=7 may be too small (~5px) when scaled to ~400px mobile — increase to 8pt
  • Hub labels "Node 3" and "Node 1" are positionally close in the dense Engineering cluster; consider reducing to top-3 hub labels to create safer separation
  • Edge styling is uniform grey regardless of edge type — differentiating cross-community bridge edges (e.g. using INK_SOFT vs EDGE_COLOR) would strengthen the structural story
  • Manual legend construction (legend=False then ax.legend(handles=[...])) is less idiomatic than using seaborn's built-in legend then appending a single bridge-node handle

Issues Found

  1. VQ-01 MINOR: Stats text at 7pt is the only explicitly sized element that may be marginal at mobile scale
    • Fix: Increase stats fontsize from 7 to 8 to match hub annotation size
  2. DE-02 IMPROVEMENT: Edge styling is uniform — all edges share the same grey color regardless of whether they are within-community or cross-community
    • Fix: Use a slightly lighter/more muted color for within-community edges and a slightly more visible color for cross-community (bridge) edges to reinforce the structural story
  3. LM-01 MINOR: Manual legend construction pattern bypasses seaborn's built-in legend
    • Fix: Let seaborn draw its own legend (remove legend=False), then use ax.get_legend() to access it and append the bridge-node handle

AI Feedback for Next Attempt

This is a strong implementation (88/100) — APPROVED. If a repair were needed, priority would be: (1) boost stats fontsize 7→8 for mobile legibility, (2) differentiate cross-community edges visually to strengthen the bridge-node story, (3) use seaborn's built-in legend mechanism for LM-01 improvement. Design Excellence (13/20) is the primary gap — the triple-encoding and selective labeling show design intent but the uniform grey edges and lack of a standout focal point limit the score.

Verdict: APPROVED

@github-actions github-actions Bot added quality:88 Quality score: 88/100 ai-approved Quality OK, ready for merge and removed quality:82 Quality score 82/100 labels Jul 1, 2026
@MarkusNeusinger MarkusNeusinger merged commit d6ab57b into main Jul 1, 2026
3 checks passed
@MarkusNeusinger MarkusNeusinger deleted the implementation/network-force-directed/seaborn branch July 1, 2026 01:34
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:88 Quality score: 88/100

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant