From 95a47d9712389f73a0735543246213f956ecc862 Mon Sep 17 00:00:00 2001 From: Markus Neusinger <2921697+MarkusNeusinger@users.noreply.github.com> Date: Mon, 6 Apr 2026 22:28:36 +0200 Subject: [PATCH 1/6] =?UTF-8?q?update(chord-basic):=20matplotlib=20?= =?UTF-8?q?=E2=80=94=20comprehensive=20review?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Comprehensive review and improvement of matplotlib chord diagram implementation. --- .../chord-basic/implementations/matplotlib.py | 182 +++++++----------- plots/chord-basic/metadata/matplotlib.yaml | 8 +- plots/chord-basic/specification.yaml | 6 +- 3 files changed, 81 insertions(+), 115 deletions(-) diff --git a/plots/chord-basic/implementations/matplotlib.py b/plots/chord-basic/implementations/matplotlib.py index 5bac8fdb48..33fba54abe 100644 --- a/plots/chord-basic/implementations/matplotlib.py +++ b/plots/chord-basic/implementations/matplotlib.py @@ -1,7 +1,7 @@ -""" pyplots.ai +"""pyplots.ai chord-basic: Basic Chord Diagram -Library: matplotlib 3.10.8 | Python 3.13.11 -Quality: 98/100 | Created: 2025-12-14 +Library: matplotlib 3.10.8 | Python 3.14 +Quality: /100 | Updated: 2026-04-06 """ import matplotlib.patches as mpatches @@ -11,11 +11,9 @@ # Data: Migration flows between continents (in millions) -np.random.seed(42) entities = ["Africa", "Asia", "Europe", "N. America", "S. America", "Oceania"] n = len(entities) -# Flow matrix (row=source, col=target) flow_matrix = np.array( [ [0, 12, 8, 5, 2, 1], # From Africa @@ -27,157 +25,123 @@ ] ) -# Colors for each entity (colorblind-safe palette) -colors = ["#306998", "#FFD43B", "#4ECDC4", "#FF6B6B", "#95E1A3", "#DDA0DD"] +# Colorblind-safe palette starting with Python Blue +colors = ["#306998", "#E69F00", "#009E73", "#D55E00", "#56B4E9", "#CC79A7"] -# Calculate totals for each entity (sum of outgoing + incoming) +# Calculate entity totals and arc geometry totals = flow_matrix.sum(axis=1) + flow_matrix.sum(axis=0) total_flow = totals.sum() +gap_deg = 3 +available_deg = 360 - gap_deg * n +arc_spans = (totals / total_flow) * available_deg -# Gap between entity arcs (in degrees) -gap = 3 -total_gap = gap * n -available_degrees = 360 - total_gap - -# Calculate arc spans for each entity -arc_spans = (totals / total_flow) * available_degrees - -# Calculate start angles for each entity arc +# Start angles (clockwise from top) start_angles = np.zeros(n) -current_angle = 90 # Start from top +angle = 90 for i in range(n): - start_angles[i] = current_angle - current_angle -= arc_spans[i] + gap + start_angles[i] = angle + angle -= arc_spans[i] + gap_deg -# Create figure +# Plot fig, ax = plt.subplots(figsize=(16, 9), subplot_kw={"aspect": "equal"}) -ax.set_xlim(-1.5, 1.5) -ax.set_ylim(-1.3, 1.3) +ax.set_xlim(-1.55, 1.55) +ax.set_ylim(-1.35, 1.35) ax.axis("off") -# Draw entity arcs on the outer ring radius = 1.0 arc_width = 0.08 +inner_r = radius - arc_width +# Draw outer arcs for i in range(n): theta1 = start_angles[i] - arc_spans[i] theta2 = start_angles[i] - - # Draw outer arc as a wedge wedge = mpatches.Wedge( (0, 0), radius, theta1, theta2, width=arc_width, facecolor=colors[i], edgecolor="white", linewidth=2 ) ax.add_patch(wedge) - # Add entity label - mid_angle = (theta1 + theta2) / 2 - label_radius = radius + 0.12 - label_x = label_radius * np.cos(np.radians(mid_angle)) - label_y = label_radius * np.sin(np.radians(mid_angle)) + # Label placement + mid = np.radians((theta1 + theta2) / 2) + lx, ly = (radius + 0.12) * np.cos(mid), (radius + 0.12) * np.sin(mid) + mid_deg = np.degrees(mid) % 360 + ha = ( + "center" + if mid_deg < 15 or mid_deg > 345 or 165 < mid_deg < 195 + else ("right" if 90 < mid_deg < 270 else "left") + ) + ax.text(lx, ly, entities[i], fontsize=18, fontweight="bold", ha=ha, va="center", color=colors[i]) - # Rotate text to align with arc - rotation = mid_angle - if mid_angle > 90 or mid_angle < -90: - rotation = mid_angle + 180 - if 90 < mid_angle < 270 or -270 < mid_angle < -90: - ha = "right" - else: - ha = "left" - if abs(mid_angle) < 10 or abs(mid_angle - 180) < 10 or abs(mid_angle + 180) < 10: - ha = "center" +# Track angular position within each arc for chord placement +arc_cursors = start_angles.copy() +unit_angles = arc_spans / totals - ax.text(label_x, label_y, entities[i], fontsize=18, fontweight="bold", ha=ha, va="center", color=colors[i]) +# Sort flows by magnitude (draw largest last for visual hierarchy) +flows = [(i, j, flow_matrix[i, j]) for i in range(n) for j in range(n) if i != j and flow_matrix[i, j] > 0] +flows.sort(key=lambda f: f[2]) +# Pre-compute chord positions to avoid cursor interference from draw order +chord_params = [] +pos_cursors = start_angles.copy() +for i in range(n): + for j in range(n): + if i != j and flow_matrix[i, j] > 0: + flow = flow_matrix[i, j] + src_span = flow * unit_angles[i] + src_end = pos_cursors[i] + src_start = src_end - src_span + pos_cursors[i] = src_start -def draw_chord(ax, start1, end1, start2, end2, color, alpha=0.65): - """Draw a chord between two arcs using Bezier curves.""" - inner_radius = radius - arc_width + tgt_span = flow * unit_angles[j] + tgt_end = pos_cursors[j] + tgt_start = tgt_end - tgt_span + pos_cursors[j] = tgt_start - # Convert angles to radians - s1, e1 = np.radians(start1), np.radians(end1) - s2, e2 = np.radians(start2), np.radians(end2) + chord_params.append((src_start, src_end, tgt_start, tgt_end, colors[i], flow)) - # Create path points - n_arc_points = 20 +# Sort by flow magnitude so largest chords render on top +chord_params.sort(key=lambda c: c[5]) - # First arc (source) - arc1_angles = np.linspace(s1, e1, n_arc_points) - arc1_points = np.column_stack([inner_radius * np.cos(arc1_angles), inner_radius * np.sin(arc1_angles)]) +# Draw chords using cubic Bezier paths +n_arc_pts = 30 +ctrl_factor = 0.25 - # Second arc (target) - arc2_angles = np.linspace(s2, e2, n_arc_points) - arc2_points = np.column_stack([inner_radius * np.cos(arc2_angles), inner_radius * np.sin(arc2_angles)]) +for src_start, src_end, tgt_start, tgt_end, color, flow in chord_params: + s1, e1 = np.radians(src_start), np.radians(src_end) + s2, e2 = np.radians(tgt_start), np.radians(tgt_end) - # Control points for Bezier curves (through center with some offset) - ctrl_factor = 0.3 + arc1_t = np.linspace(s1, e1, n_arc_pts) + arc1 = np.column_stack([inner_r * np.cos(arc1_t), inner_r * np.sin(arc1_t)]) - # Build path: arc1 -> bezier to arc2 -> arc2 -> bezier back to arc1 - verts = [] - codes = [] + arc2_t = np.linspace(s2, e2, n_arc_pts) + arc2 = np.column_stack([inner_r * np.cos(arc2_t), inner_r * np.sin(arc2_t)]) - # Start at first point of arc1 - verts.append(arc1_points[0]) - codes.append(Path.MOVETO) + # Build closed path: arc1 → bezier → arc2 → bezier → close + verts = [arc1[0]] + codes = [Path.MOVETO] - # Arc1 points - for pt in arc1_points[1:]: + for pt in arc1[1:]: verts.append(pt) codes.append(Path.LINETO) - # Bezier curve from end of arc1 to start of arc2 - ctrl1 = arc1_points[-1] * ctrl_factor - ctrl2 = arc2_points[0] * ctrl_factor - verts.extend([ctrl1, ctrl2, arc2_points[0]]) + verts.extend([arc1[-1] * ctrl_factor, arc2[0] * ctrl_factor, arc2[0]]) codes.extend([Path.CURVE4, Path.CURVE4, Path.CURVE4]) - # Arc2 points - for pt in arc2_points[1:]: + for pt in arc2[1:]: verts.append(pt) codes.append(Path.LINETO) - # Bezier curve from end of arc2 back to start of arc1 - ctrl3 = arc2_points[-1] * ctrl_factor - ctrl4 = arc1_points[0] * ctrl_factor - verts.extend([ctrl3, ctrl4, arc1_points[0]]) + verts.extend([arc2[-1] * ctrl_factor, arc1[0] * ctrl_factor, arc1[0]]) codes.extend([Path.CURVE4, Path.CURVE4, Path.CURVE4]) - path = Path(verts, codes) - patch = mpatches.PathPatch(path, facecolor=color, edgecolor="none", alpha=alpha) + # Scale alpha by flow magnitude for visual depth + alpha = 0.45 + 0.25 * (flow / flow_matrix.max()) + patch = mpatches.PathPatch(Path(verts, codes), facecolor=color, edgecolor=color, linewidth=0.3, alpha=alpha) ax.add_patch(patch) - -# Track position within each entity arc for placing chords -arc_positions = {} -for i in range(n): - arc_positions[i] = {"out": start_angles[i], "in": start_angles[i]} - -# Calculate the angular span each flow unit represents for each entity -unit_angles = arc_spans / totals - -# Draw chords for each flow -for i in range(n): - for j in range(n): - if i != j and flow_matrix[i, j] > 0: - flow = flow_matrix[i, j] - - # Calculate chord width at source (outgoing from entity i) - source_span = flow * unit_angles[i] - source_start = arc_positions[i]["out"] - source_span - source_end = arc_positions[i]["out"] - arc_positions[i]["out"] = source_start - - # Calculate chord width at target (incoming to entity j) - target_span = flow * unit_angles[j] - target_start = arc_positions[j]["in"] - target_span - target_end = arc_positions[j]["in"] - arc_positions[j]["in"] = target_start - - # Draw the chord (use source color) - draw_chord(ax, source_start, source_end, target_start, target_end, colors[i]) - # Title ax.set_title( - "Continental Migration Flows · chord-basic · matplotlib · pyplots.ai", fontsize=24, fontweight="bold", pad=20 + "Continental Migration Flows · chord-basic · matplotlib · pyplots.ai", fontsize=24, fontweight="medium", pad=30 ) plt.tight_layout() diff --git a/plots/chord-basic/metadata/matplotlib.yaml b/plots/chord-basic/metadata/matplotlib.yaml index 510da20ac8..14307d0a18 100644 --- a/plots/chord-basic/metadata/matplotlib.yaml +++ b/plots/chord-basic/metadata/matplotlib.yaml @@ -1,15 +1,15 @@ library: matplotlib specification_id: chord-basic created: 2025-12-14 19:45:02+00:00 -updated: 2025-12-14 19:45:02+00:00 -generated_by: claude-opus-4-5-20251101 +updated: 2026-04-06T20:26:19+00:00 +generated_by: claude-opus-4-6 workflow_run: 20213174710 issue: 858 -python_version: 3.13.11 +python_version: '3.14' library_version: 3.10.8 preview_url: https://storage.googleapis.com/pyplots-images/plots/chord-basic/matplotlib/plot.png preview_html: null -quality_score: 98 +quality_score: null impl_tags: dependencies: [] techniques: diff --git a/plots/chord-basic/specification.yaml b/plots/chord-basic/specification.yaml index 34c47b8560..696903da2d 100644 --- a/plots/chord-basic/specification.yaml +++ b/plots/chord-basic/specification.yaml @@ -6,7 +6,7 @@ title: Basic Chord Diagram # Specification tracking created: 2025-12-14T19:33:31Z -updated: 2025-12-14T19:33:31Z +updated: 2026-04-06T12:00:00Z issue: 858 suggested: MarkusNeusinger @@ -16,6 +16,8 @@ tags: - chord - flow data_type: + - categorical + - numeric - network - relational domain: @@ -23,4 +25,4 @@ tags: features: - basic - circular - - connection-visualization + - proportional From c8539444ec26fd3a7aab4321131d1ce15bc1e005 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 6 Apr 2026 20:33:09 +0000 Subject: [PATCH 2/6] chore(matplotlib): update quality score 88 and review feedback for chord-basic --- .../chord-basic/implementations/matplotlib.py | 4 +- plots/chord-basic/metadata/matplotlib.yaml | 211 +++++++++++++++++- 2 files changed, 206 insertions(+), 9 deletions(-) diff --git a/plots/chord-basic/implementations/matplotlib.py b/plots/chord-basic/implementations/matplotlib.py index 33fba54abe..c2b9ca65bf 100644 --- a/plots/chord-basic/implementations/matplotlib.py +++ b/plots/chord-basic/implementations/matplotlib.py @@ -1,7 +1,7 @@ -"""pyplots.ai +""" pyplots.ai chord-basic: Basic Chord Diagram Library: matplotlib 3.10.8 | Python 3.14 -Quality: /100 | Updated: 2026-04-06 +Quality: 88/100 | Created: 2026-04-06 """ import matplotlib.patches as mpatches diff --git a/plots/chord-basic/metadata/matplotlib.yaml b/plots/chord-basic/metadata/matplotlib.yaml index 14307d0a18..e2a730a870 100644 --- a/plots/chord-basic/metadata/matplotlib.yaml +++ b/plots/chord-basic/metadata/matplotlib.yaml @@ -1,7 +1,7 @@ library: matplotlib specification_id: chord-basic created: 2025-12-14 19:45:02+00:00 -updated: 2026-04-06T20:26:19+00:00 +updated: '2026-04-06T20:33:09Z' generated_by: claude-opus-4-6 workflow_run: 20213174710 issue: 858 @@ -9,23 +9,220 @@ python_version: '3.14' library_version: 3.10.8 preview_url: https://storage.googleapis.com/pyplots-images/plots/chord-basic/matplotlib/plot.png preview_html: null -quality_score: null +quality_score: 88 impl_tags: dependencies: [] techniques: - bezier-curves - patches - - manual-ticks + - annotations patterns: - data-generation - matrix-construction - iteration-over-groups dataprep: [] styling: - - alpha-blending - minimal-chrome + - alpha-blending + - edge-highlighting review: - strengths: [] - weaknesses: [] + strengths: + - Excellent use of matplotlib's low-level Path/Patch API to build a chord diagram + from scratch + - Colorblind-safe Wong palette with colored entity labels matching arcs + - Alpha variation by flow magnitude and draw-order sorting create effective visual + hierarchy + - Clean, well-structured code with deterministic data and proper geometry calculations + - Bidirectional flows correctly represented as separate chords + weaknesses: + - Entity label font size (18pt) slightly below the 20pt guideline for optimal legibility + - 16:9 aspect ratio wastes horizontal space for a circular chart — square would + be more appropriate + - Some smaller chords (Oceania connections) are very thin and hard to distinguish + - Could benefit from additional visual polish to reach publication quality improvements: [] - verdict: APPROVED + verdict: REJECTED + image_description: 'The plot displays a chord diagram showing continental migration + flows between six continents: Africa (dark blue, top-right), Asia (amber/gold, + right), Europe (teal, bottom), N. America (burnt orange, left), S. America (light + blue, upper-left), and Oceania (pink/mauve, top). Each continent has a proportional + arc segment around the circle perimeter with white edge separation. Chords connect + arcs with widths proportional to flow magnitude. Chord colors match their source + continent with alpha transparency varying by flow size. Larger chords (e.g., Asia-Europe, + Africa-Asia) are drawn on top for visual prominence. Entity labels are bold, colored + to match their arcs, positioned outside the circle. Title reads "Continental Migration + Flows · chord-basic · matplotlib · pyplots.ai" at the top. White background, axes + turned off, clean layout.' + criteria_checklist: + visual_quality: + score: 27 + max: 30 + items: + - id: VQ-01 + name: Text Legibility + score: 7 + max: 8 + passed: true + comment: Title at 24pt, labels at 18pt bold. All readable but entity labels + slightly under 20pt guideline. + - id: VQ-02 + name: No Overlap + score: 6 + max: 6 + passed: true + comment: All labels well-positioned with no collisions. + - id: VQ-03 + name: Element Visibility + score: 5 + max: 6 + passed: true + comment: Most chords clearly visible; some smaller flows (Oceania connections) + are quite thin. + - id: VQ-04 + name: Color Accessibility + score: 4 + max: 4 + passed: true + comment: Colorblind-safe Wong palette with good contrast between all six colors. + - id: VQ-05 + name: Layout & Canvas + score: 3 + max: 4 + passed: true + comment: 16:9 aspect ratio creates wasted horizontal space for circular chart. + Square format would be better. + - id: VQ-06 + name: Axis Labels & Title + score: 2 + max: 2 + passed: true + comment: Descriptive title with proper format. No axes needed for chord diagrams. + design_excellence: + score: 14 + max: 20 + items: + - id: DE-01 + name: Aesthetic Sophistication + score: 6 + max: 8 + passed: true + comment: Custom colorblind-safe palette, colored labels, alpha variation. + Clearly above defaults. + - id: DE-02 + name: Visual Refinement + score: 4 + max: 6 + passed: true + comment: Axes hidden, clean background, white edge separation. Good but could + push further. + - id: DE-03 + name: Data Storytelling + score: 4 + max: 6 + passed: true + comment: Alpha variation and draw order create effective visual hierarchy. + Dominant flows immediately apparent. + spec_compliance: + score: 15 + max: 15 + items: + - id: SC-01 + name: Plot Type + score: 5 + max: 5 + passed: true + comment: Correct chord diagram with entities around circle connected by chords. + - id: SC-02 + name: Required Features + score: 4 + max: 4 + passed: true + comment: Distinct colors, proportional chord widths, bidirectional flows all + present. + - id: SC-03 + name: Data Mapping + score: 3 + max: 3 + passed: true + comment: 6 continents with bidirectional flow matrix correctly mapped. + - id: SC-04 + name: Title & Legend + score: 3 + max: 3 + passed: true + comment: Title follows format. Colored labels serve as legend for chord diagrams. + data_quality: + score: 14 + max: 15 + items: + - id: DQ-01 + name: Feature Coverage + score: 5 + max: 6 + passed: true + comment: Shows bidirectional flows, varying magnitudes, asymmetric relationships. + - id: DQ-02 + name: Realistic Context + score: 5 + max: 5 + passed: true + comment: Intercontinental migration flows — real, neutral, comprehensible + scenario. + - id: DQ-03 + name: Appropriate Scale + score: 4 + max: 4 + passed: true + comment: Values in millions, realistic magnitudes for intercontinental migration. + code_quality: + score: 10 + max: 10 + items: + - id: CQ-01 + name: KISS Structure + score: 3 + max: 3 + passed: true + comment: 'Linear flow: imports, data, geometry, plot, save. No functions/classes.' + - id: CQ-02 + name: Reproducibility + score: 2 + max: 2 + passed: true + comment: Fully deterministic with hardcoded flow matrix. + - id: CQ-03 + name: Clean Imports + score: 2 + max: 2 + passed: true + comment: 'All imports used: matplotlib.patches, pyplot, numpy, Path.' + - id: CQ-04 + name: Code Elegance + score: 2 + max: 2 + passed: true + comment: Well-structured Bezier chord construction. Appropriate complexity. + - id: CQ-05 + name: Output & API + score: 1 + max: 1 + passed: true + comment: Saves as plot.png with dpi=300 and bbox_inches='tight'. + library_mastery: + score: 8 + max: 10 + items: + - id: LM-01 + name: Idiomatic Usage + score: 4 + max: 5 + passed: true + comment: Uses matplotlib patches and Path with Bezier curves — correct approach + for chord diagrams. + - id: LM-02 + name: Distinctive Features + score: 4 + max: 5 + passed: true + comment: Path with CURVE4 Bezier, mpatches.Wedge, custom PathPatch — distinctively + matplotlib. From f8957fc6dc600abaf6c376f9dbf8d28bd618b0cd Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 6 Apr 2026 20:36:29 +0000 Subject: [PATCH 3/6] fix(matplotlib): address review feedback for chord-basic Attempt 1/3 - fixes based on AI review --- .../chord-basic/implementations/matplotlib.py | 35 +++++++++++-------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/plots/chord-basic/implementations/matplotlib.py b/plots/chord-basic/implementations/matplotlib.py index c2b9ca65bf..617561ed36 100644 --- a/plots/chord-basic/implementations/matplotlib.py +++ b/plots/chord-basic/implementations/matplotlib.py @@ -1,7 +1,7 @@ -""" pyplots.ai +"""pyplots.ai chord-basic: Basic Chord Diagram Library: matplotlib 3.10.8 | Python 3.14 -Quality: 88/100 | Created: 2026-04-06 +Created: 2026-04-06 """ import matplotlib.patches as mpatches @@ -42,14 +42,16 @@ start_angles[i] = angle angle -= arc_spans[i] + gap_deg -# Plot -fig, ax = plt.subplots(figsize=(16, 9), subplot_kw={"aspect": "equal"}) -ax.set_xlim(-1.55, 1.55) -ax.set_ylim(-1.35, 1.35) +# Plot — square canvas for circular chart +fig, ax = plt.subplots(figsize=(12, 12), subplot_kw={"aspect": "equal"}) +fig.set_facecolor("#FAFAFA") +ax.set_xlim(-1.45, 1.45) +ax.set_ylim(-1.45, 1.45) +ax.set_facecolor("#FAFAFA") ax.axis("off") radius = 1.0 -arc_width = 0.08 +arc_width = 0.09 inner_r = radius - arc_width # Draw outer arcs @@ -70,7 +72,7 @@ if mid_deg < 15 or mid_deg > 345 or 165 < mid_deg < 195 else ("right" if 90 < mid_deg < 270 else "left") ) - ax.text(lx, ly, entities[i], fontsize=18, fontweight="bold", ha=ha, va="center", color=colors[i]) + ax.text(lx, ly, entities[i], fontsize=20, fontweight="bold", ha=ha, va="center", color=colors[i]) # Track angular position within each arc for chord placement arc_cursors = start_angles.copy() @@ -81,18 +83,19 @@ flows.sort(key=lambda f: f[2]) # Pre-compute chord positions to avoid cursor interference from draw order +min_chord_deg = 1.5 # minimum angular span for visibility chord_params = [] pos_cursors = start_angles.copy() for i in range(n): for j in range(n): if i != j and flow_matrix[i, j] > 0: flow = flow_matrix[i, j] - src_span = flow * unit_angles[i] + src_span = max(flow * unit_angles[i], min_chord_deg) src_end = pos_cursors[i] src_start = src_end - src_span pos_cursors[i] = src_start - tgt_span = flow * unit_angles[j] + tgt_span = max(flow * unit_angles[j], min_chord_deg) tgt_end = pos_cursors[j] tgt_start = tgt_end - tgt_span pos_cursors[j] = tgt_start @@ -135,14 +138,18 @@ codes.extend([Path.CURVE4, Path.CURVE4, Path.CURVE4]) # Scale alpha by flow magnitude for visual depth - alpha = 0.45 + 0.25 * (flow / flow_matrix.max()) - patch = mpatches.PathPatch(Path(verts, codes), facecolor=color, edgecolor=color, linewidth=0.3, alpha=alpha) + alpha = 0.40 + 0.30 * (flow / flow_matrix.max()) + patch = mpatches.PathPatch(Path(verts, codes), facecolor=color, edgecolor=color, linewidth=0.5, alpha=alpha) ax.add_patch(patch) # Title ax.set_title( - "Continental Migration Flows · chord-basic · matplotlib · pyplots.ai", fontsize=24, fontweight="medium", pad=30 + "Continental Migration Flows · chord-basic · matplotlib · pyplots.ai", + fontsize=24, + fontweight="medium", + pad=30, + color="#333333", ) plt.tight_layout() -plt.savefig("plot.png", dpi=300, bbox_inches="tight", facecolor="white") +plt.savefig("plot.png", dpi=300, bbox_inches="tight", facecolor="#FAFAFA") From 177fb1f43c5e32cac03bff944c6065098f58652a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 6 Apr 2026 20:40:17 +0000 Subject: [PATCH 4/6] chore(matplotlib): update quality score 87 and review feedback for chord-basic --- .../chord-basic/implementations/matplotlib.py | 4 +- plots/chord-basic/metadata/matplotlib.yaml | 120 ++++++++---------- 2 files changed, 58 insertions(+), 66 deletions(-) diff --git a/plots/chord-basic/implementations/matplotlib.py b/plots/chord-basic/implementations/matplotlib.py index 617561ed36..8e7ca8e6a9 100644 --- a/plots/chord-basic/implementations/matplotlib.py +++ b/plots/chord-basic/implementations/matplotlib.py @@ -1,7 +1,7 @@ -"""pyplots.ai +""" pyplots.ai chord-basic: Basic Chord Diagram Library: matplotlib 3.10.8 | Python 3.14 -Created: 2026-04-06 +Quality: 87/100 | Created: 2026-04-06 """ import matplotlib.patches as mpatches diff --git a/plots/chord-basic/metadata/matplotlib.yaml b/plots/chord-basic/metadata/matplotlib.yaml index e2a730a870..4075a4869a 100644 --- a/plots/chord-basic/metadata/matplotlib.yaml +++ b/plots/chord-basic/metadata/matplotlib.yaml @@ -1,7 +1,7 @@ library: matplotlib specification_id: chord-basic created: 2025-12-14 19:45:02+00:00 -updated: '2026-04-06T20:33:09Z' +updated: '2026-04-06T20:40:16Z' generated_by: claude-opus-4-6 workflow_run: 20213174710 issue: 858 @@ -9,7 +9,7 @@ python_version: '3.14' library_version: 3.10.8 preview_url: https://storage.googleapis.com/pyplots-images/plots/chord-basic/matplotlib/plot.png preview_html: null -quality_score: 88 +quality_score: 87 impl_tags: dependencies: [] techniques: @@ -27,35 +27,31 @@ impl_tags: - edge-highlighting review: strengths: - - Excellent use of matplotlib's low-level Path/Patch API to build a chord diagram - from scratch - - Colorblind-safe Wong palette with colored entity labels matching arcs - - Alpha variation by flow magnitude and draw-order sorting create effective visual - hierarchy - - Clean, well-structured code with deterministic data and proper geometry calculations - - Bidirectional flows correctly represented as separate chords + - Excellent custom Bezier chord rendering with proper arc-based positioning + - Alpha scaling by flow magnitude creates effective visual depth + - Colorblind-safe palette with strong contrast against off-white background + - Smart pre-computation of chord positions to decouple draw order from layout + - Perfect spec compliance — all required features implemented correctly weaknesses: - - Entity label font size (18pt) slightly below the 20pt guideline for optimal legibility - - 16:9 aspect ratio wastes horizontal space for a circular chart — square would - be more appropriate - - Some smaller chords (Oceania connections) are very thin and hard to distinguish - - Could benefit from additional visual polish to reach publication quality + - Center area is busy — hard to trace individual flows through the middle + - No visual emphasis on the most important relationships (top flows look similar + to mid-range) + - Data storytelling could be stronger — viewer must discover insights rather than + being guided improvements: [] verdict: REJECTED image_description: 'The plot displays a chord diagram showing continental migration - flows between six continents: Africa (dark blue, top-right), Asia (amber/gold, - right), Europe (teal, bottom), N. America (burnt orange, left), S. America (light - blue, upper-left), and Oceania (pink/mauve, top). Each continent has a proportional - arc segment around the circle perimeter with white edge separation. Chords connect - arcs with widths proportional to flow magnitude. Chord colors match their source - continent with alpha transparency varying by flow size. Larger chords (e.g., Asia-Europe, - Africa-Asia) are drawn on top for visual prominence. Entity labels are bold, colored - to match their arcs, positioned outside the circle. Title reads "Continental Migration - Flows · chord-basic · matplotlib · pyplots.ai" at the top. White background, axes - turned off, clean layout.' + flows between 6 continents arranged clockwise from top-right: Africa (dark blue), + Asia (amber/gold), Europe (teal), N. America (red-orange), S. America (light blue), + and Oceania (pink). Outer arcs are proportional to each continent''s total flow + volume — Asia and Europe have the largest arcs. Chords connect continents with + widths proportional to migration magnitude and alpha-blended by flow size (larger + flows more opaque). The background is a subtle off-white (#FAFAFA). Title reads + "Continental Migration Flows · chord-basic · matplotlib · pyplots.ai" at the top. + Labels are bold, colored to match their arc segments.' criteria_checklist: visual_quality: - score: 27 + score: 28 max: 30 items: - id: VQ-01 @@ -63,42 +59,40 @@ review: score: 7 max: 8 passed: true - comment: Title at 24pt, labels at 18pt bold. All readable but entity labels - slightly under 20pt guideline. + comment: Title 24pt, labels 20pt bold, all explicitly set and readable - id: VQ-02 name: No Overlap score: 6 max: 6 passed: true - comment: All labels well-positioned with no collisions. + comment: Labels placed outside circle with intelligent alignment, no collisions - id: VQ-03 name: Element Visibility score: 5 max: 6 passed: true - comment: Most chords clearly visible; some smaller flows (Oceania connections) - are quite thin. + comment: Chords mostly distinguishable; minimum chord angle ensures small + flows visible; some center blending - id: VQ-04 name: Color Accessibility score: 4 max: 4 passed: true - comment: Colorblind-safe Wong palette with good contrast between all six colors. + comment: Wong colorblind-safe palette variant with good contrast - id: VQ-05 name: Layout & Canvas - score: 3 + score: 4 max: 4 passed: true - comment: 16:9 aspect ratio creates wasted horizontal space for circular chart. - Square format would be better. + comment: Square 12x12 canvas, circle well-centered with balanced margins - id: VQ-06 name: Axis Labels & Title score: 2 max: 2 passed: true - comment: Descriptive title with proper format. No axes needed for chord diagrams. + comment: Descriptive title with context, no axes needed for circular layout design_excellence: - score: 14 + score: 13 max: 20 items: - id: DE-01 @@ -106,22 +100,21 @@ review: score: 6 max: 8 passed: true - comment: Custom colorblind-safe palette, colored labels, alpha variation. - Clearly above defaults. + comment: Custom palette, off-white background, alpha-scaled chords, white + edge separators - id: DE-02 name: Visual Refinement score: 4 max: 6 passed: true - comment: Axes hidden, clean background, white edge separation. Good but could - push further. + comment: Axes hidden, custom background, white arc separators, 3-degree gaps - id: DE-03 name: Data Storytelling - score: 4 + score: 3 max: 6 - passed: true - comment: Alpha variation and draw order create effective visual hierarchy. - Dominant flows immediately apparent. + passed: false + comment: Alpha scaling creates some hierarchy but center is busy; no clear + focal point spec_compliance: score: 15 max: 15 @@ -131,26 +124,26 @@ review: score: 5 max: 5 passed: true - comment: Correct chord diagram with entities around circle connected by chords. + comment: Correct chord diagram with circular perimeter layout - id: SC-02 name: Required Features score: 4 max: 4 passed: true - comment: Distinct colors, proportional chord widths, bidirectional flows all - present. + comment: Distinct colors, proportional widths, bidirectional flows, 6 entities - id: SC-03 name: Data Mapping score: 3 max: 3 passed: true - comment: 6 continents with bidirectional flow matrix correctly mapped. + comment: Flow matrix correctly mapped to arc sizes and chord widths - id: SC-04 name: Title & Legend score: 3 max: 3 passed: true - comment: Title follows format. Colored labels serve as legend for chord diagrams. + comment: Title includes descriptive prefix + required format; colored labels + as legend data_quality: score: 14 max: 15 @@ -160,20 +153,20 @@ review: score: 5 max: 6 passed: true - comment: Shows bidirectional flows, varying magnitudes, asymmetric relationships. + comment: Bidirectional asymmetric flows, varying magnitudes, different entity + sizes - id: DQ-02 name: Realistic Context score: 5 max: 5 passed: true - comment: Intercontinental migration flows — real, neutral, comprehensible - scenario. + comment: Continental migration flows in millions — neutral, real-world scenario - id: DQ-03 name: Appropriate Scale score: 4 max: 4 passed: true - comment: Values in millions, realistic magnitudes for intercontinental migration. + comment: Values 1-15 million plausible for intercontinental migration code_quality: score: 10 max: 10 @@ -183,46 +176,45 @@ review: score: 3 max: 3 passed: true - comment: 'Linear flow: imports, data, geometry, plot, save. No functions/classes.' + comment: Linear flow with no functions or classes - id: CQ-02 name: Reproducibility score: 2 max: 2 passed: true - comment: Fully deterministic with hardcoded flow matrix. + comment: Fully deterministic hardcoded matrix - id: CQ-03 name: Clean Imports score: 2 max: 2 passed: true - comment: 'All imports used: matplotlib.patches, pyplot, numpy, Path.' + comment: All 4 imports used - id: CQ-04 name: Code Elegance score: 2 max: 2 passed: true - comment: Well-structured Bezier chord construction. Appropriate complexity. + comment: Smart pre-computation of chord positions, clean alpha formula - id: CQ-05 name: Output & API score: 1 max: 1 passed: true - comment: Saves as plot.png with dpi=300 and bbox_inches='tight'. + comment: Saves as plot.png, dpi=300, bbox_inches=tight library_mastery: - score: 8 + score: 7 max: 10 items: - id: LM-01 name: Idiomatic Usage - score: 4 + score: 3 max: 5 passed: true - comment: Uses matplotlib patches and Path with Bezier curves — correct approach - for chord diagrams. + comment: Correct use of patches and Path API but very low-level approach - id: LM-02 name: Distinctive Features score: 4 max: 5 passed: true - comment: Path with CURVE4 Bezier, mpatches.Wedge, custom PathPatch — distinctively - matplotlib. + comment: Bezier curves via Path CURVE4, mpatches.Wedge, PathPatch — distinctively + matplotlib From 2becacfdbd93496609063512a200bb1ab728209e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 6 Apr 2026 20:43:39 +0000 Subject: [PATCH 5/6] fix(matplotlib): address review feedback for chord-basic Attempt 2/3 - fixes based on AI review --- .../chord-basic/implementations/matplotlib.py | 53 ++++++++++++++++--- 1 file changed, 47 insertions(+), 6 deletions(-) diff --git a/plots/chord-basic/implementations/matplotlib.py b/plots/chord-basic/implementations/matplotlib.py index 8e7ca8e6a9..8eb48be70b 100644 --- a/plots/chord-basic/implementations/matplotlib.py +++ b/plots/chord-basic/implementations/matplotlib.py @@ -1,4 +1,4 @@ -""" pyplots.ai +"""pyplots.ai chord-basic: Basic Chord Diagram Library: matplotlib 3.10.8 | Python 3.14 Quality: 87/100 | Created: 2026-04-06 @@ -137,19 +137,60 @@ verts.extend([arc2[-1] * ctrl_factor, arc1[0] * ctrl_factor, arc1[0]]) codes.extend([Path.CURVE4, Path.CURVE4, Path.CURVE4]) - # Scale alpha by flow magnitude for visual depth - alpha = 0.40 + 0.30 * (flow / flow_matrix.max()) - patch = mpatches.PathPatch(Path(verts, codes), facecolor=color, edgecolor=color, linewidth=0.5, alpha=alpha) + # Scale alpha and linewidth by flow magnitude for clear visual hierarchy + flow_ratio = flow / flow_matrix.max() + alpha = 0.15 + 0.65 * flow_ratio**0.7 + lw = 0.3 + 1.2 * flow_ratio + patch = mpatches.PathPatch(Path(verts, codes), facecolor=color, edgecolor=color, linewidth=lw, alpha=alpha) ax.add_patch(patch) -# Title +# Annotate the top 3 flows to create a clear data story +top_flows = sorted( + [(i, j, flow_matrix[i, j]) for i in range(n) for j in range(n) if i != j and flow_matrix[i, j] > 0], + key=lambda f: f[2], + reverse=True, +)[:3] + +ann_positions = [(-0.55, -1.28), (0.55, 1.20), (-0.95, 0.60)] +for rank, (i, j, flow) in enumerate(top_flows): + ax_x, ax_y = ann_positions[rank] + label = f"{entities[i]} → {entities[j]}: {flow}M" + fs = 14 if rank == 0 else 12 + ax.annotate( + label, + xy=(ax_x, ax_y), + fontsize=fs, + fontweight="bold" if rank == 0 else "medium", + ha="center", + va="center", + color="#333333", + bbox={ + "boxstyle": "round,pad=0.3", + "facecolor": "white", + "edgecolor": colors[i], + "alpha": 0.92, + "linewidth": 1.5, + }, + ) + +# Title and subtitle ax.set_title( "Continental Migration Flows · chord-basic · matplotlib · pyplots.ai", fontsize=24, fontweight="medium", - pad=30, + pad=40, color="#333333", ) +ax.text( + 0, + 1.38, + "Asia–Europe corridor dominates global flows", + fontsize=16, + ha="center", + va="center", + color="#666666", + fontstyle="italic", +) plt.tight_layout() plt.savefig("plot.png", dpi=300, bbox_inches="tight", facecolor="#FAFAFA") From 8d570b36c3264a45b5044830582f239779732732 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 6 Apr 2026 20:47:55 +0000 Subject: [PATCH 6/6] chore(matplotlib): update quality score 90 and review feedback for chord-basic --- .../chord-basic/implementations/matplotlib.py | 4 +- plots/chord-basic/metadata/matplotlib.yaml | 130 ++++++++++-------- 2 files changed, 73 insertions(+), 61 deletions(-) diff --git a/plots/chord-basic/implementations/matplotlib.py b/plots/chord-basic/implementations/matplotlib.py index 8eb48be70b..a811edb914 100644 --- a/plots/chord-basic/implementations/matplotlib.py +++ b/plots/chord-basic/implementations/matplotlib.py @@ -1,7 +1,7 @@ -"""pyplots.ai +""" pyplots.ai chord-basic: Basic Chord Diagram Library: matplotlib 3.10.8 | Python 3.14 -Quality: 87/100 | Created: 2026-04-06 +Quality: 90/100 | Created: 2026-04-06 """ import matplotlib.patches as mpatches diff --git a/plots/chord-basic/metadata/matplotlib.yaml b/plots/chord-basic/metadata/matplotlib.yaml index 4075a4869a..6e80b5d8af 100644 --- a/plots/chord-basic/metadata/matplotlib.yaml +++ b/plots/chord-basic/metadata/matplotlib.yaml @@ -1,7 +1,7 @@ library: matplotlib specification_id: chord-basic created: 2025-12-14 19:45:02+00:00 -updated: '2026-04-06T20:40:16Z' +updated: '2026-04-06T20:47:55Z' generated_by: claude-opus-4-6 workflow_run: 20213174710 issue: 858 @@ -9,7 +9,7 @@ python_version: '3.14' library_version: 3.10.8 preview_url: https://storage.googleapis.com/pyplots-images/plots/chord-basic/matplotlib/plot.png preview_html: null -quality_score: 87 +quality_score: 90 impl_tags: dependencies: [] techniques: @@ -27,31 +27,34 @@ impl_tags: - edge-highlighting review: strengths: - - Excellent custom Bezier chord rendering with proper arc-based positioning - - Alpha scaling by flow magnitude creates effective visual depth - - Colorblind-safe palette with strong contrast against off-white background - - Smart pre-computation of chord positions to decouple draw order from layout - - Perfect spec compliance — all required features implemented correctly + - Excellent data storytelling with subtitle, annotated top flows, and alpha/linewidth + hierarchy + - Custom Bezier chord rendering with proper angular positioning and pre-computed + cursor tracking + - Colorblind-safe palette with color-coordinated entity labels + - Clean, well-structured code with smart geometry calculations weaknesses: - - Center area is busy — hard to trace individual flows through the middle - - No visual emphasis on the most important relationships (top flows look similar - to mid-range) - - Data storytelling could be stronger — viewer must discover insights rather than - being guided + - Annotation boxes float without visual connection (arrows/lines) to the specific + chords they describe + - Smallest chords (Oceania connections) are very faint at ~0.15 alpha improvements: [] - verdict: REJECTED - image_description: 'The plot displays a chord diagram showing continental migration - flows between 6 continents arranged clockwise from top-right: Africa (dark blue), - Asia (amber/gold), Europe (teal), N. America (red-orange), S. America (light blue), - and Oceania (pink). Outer arcs are proportional to each continent''s total flow - volume — Asia and Europe have the largest arcs. Chords connect continents with - widths proportional to migration magnitude and alpha-blended by flow size (larger - flows more opaque). The background is a subtle off-white (#FAFAFA). Title reads - "Continental Migration Flows · chord-basic · matplotlib · pyplots.ai" at the top. - Labels are bold, colored to match their arc segments.' + verdict: APPROVED + image_description: 'The plot displays a chord diagram on a light gray (#FAFAFA) + background with 6 continents arranged clockwise from the top: Africa (dark blue), + Asia (amber/gold), Europe (teal/green), N. America (burnt orange), S. America + (light blue), and Oceania (pink/mauve). Each entity has a colored outer arc segment + proportional to its total flow, with white edge separators between segments and + 3-degree gaps. Chords connect entities through the interior using cubic Bezier + curves, colored by source entity with alpha and linewidth scaled by flow magnitude + — the largest chords (Asia→Europe at 15M) are bold and opaque while smaller flows + (Oceania connections) are faint and thin. Three annotation boxes with rounded + corners highlight the top flows: "Asia → Europe: 15M" at bottom, "Africa → Asia: + 12M" at upper right, and "N. America → Europe: 12M" at left. A subtitle in italic + gray reads "Asia–Europe corridor dominates global flows." The title follows the + required format: "Continental Migration Flows · chord-basic · matplotlib · pyplots.ai".' criteria_checklist: visual_quality: - score: 28 + score: 27 max: 30 items: - id: VQ-01 @@ -59,40 +62,43 @@ review: score: 7 max: 8 passed: true - comment: Title 24pt, labels 20pt bold, all explicitly set and readable + comment: All font sizes explicitly set (title 24pt, labels 20pt bold, subtitle + 16pt). Annotations at 12-14pt slightly small but readable. - id: VQ-02 name: No Overlap - score: 6 + score: 5 max: 6 passed: true - comment: Labels placed outside circle with intelligent alignment, no collisions + comment: Entity labels well-positioned with smart alignment logic. No text + overlap. Chord crossings inherent to chart type. - id: VQ-03 name: Element Visibility score: 5 max: 6 passed: true - comment: Chords mostly distinguishable; minimum chord angle ensures small - flows visible; some center blending + comment: Alpha/linewidth scaling creates good hierarchy. Minimum chord degree + ensures small flows visible, though Oceania connections quite faint. - id: VQ-04 name: Color Accessibility score: 4 max: 4 passed: true - comment: Wong colorblind-safe palette variant with good contrast + comment: Colorblind-safe Wong palette with good contrast on light background. - id: VQ-05 name: Layout & Canvas score: 4 max: 4 passed: true - comment: Square 12x12 canvas, circle well-centered with balanced margins + comment: Square 12x12 canvas ideal for circular diagram. Chart fills canvas + well. - id: VQ-06 name: Axis Labels & Title score: 2 max: 2 passed: true - comment: Descriptive title with context, no axes needed for circular layout + comment: Axes correctly hidden for chord diagram. Title descriptive with context. design_excellence: - score: 13 + score: 16 max: 20 items: - id: DE-01 @@ -100,21 +106,23 @@ review: score: 6 max: 8 passed: true - comment: Custom palette, off-white background, alpha-scaled chords, white - edge separators + comment: Custom colorblind-safe palette, color-matched entity labels, warm + background, white edge separators, alpha/linewidth scaling. Clearly above + defaults. - id: DE-02 name: Visual Refinement - score: 4 + score: 5 max: 6 passed: true - comment: Axes hidden, custom background, white arc separators, 3-degree gaps + comment: Axes off, custom background, white edge lines, 3-degree gap spacing, + generous whitespace. - id: DE-03 name: Data Storytelling - score: 3 + score: 5 max: 6 - passed: false - comment: Alpha scaling creates some hierarchy but center is busy; no clear - focal point + passed: true + comment: Strong subtitle, annotated top 3 flows with styled callout boxes, + alpha/linewidth hierarchy for visual emphasis. spec_compliance: score: 15 max: 15 @@ -124,26 +132,27 @@ review: score: 5 max: 5 passed: true - comment: Correct chord diagram with circular perimeter layout + comment: Correct chord diagram with perimeter arcs and Bezier-curve chords. - id: SC-02 name: Required Features score: 4 max: 4 passed: true - comment: Distinct colors, proportional widths, bidirectional flows, 6 entities + comment: Distinct colors, proportional chord width, bidirectional flows, 6 + continents. - id: SC-03 name: Data Mapping score: 3 max: 3 passed: true - comment: Flow matrix correctly mapped to arc sizes and chord widths + comment: Flow matrix correctly maps source to target with proper angular allocation. - id: SC-04 name: Title & Legend score: 3 max: 3 passed: true - comment: Title includes descriptive prefix + required format; colored labels - as legend + comment: Title follows required format. Color-matched entity labels serve + as legend. data_quality: score: 14 max: 15 @@ -153,20 +162,20 @@ review: score: 5 max: 6 passed: true - comment: Bidirectional asymmetric flows, varying magnitudes, different entity - sizes + comment: Shows bidirectional asymmetric flows, varying magnitudes 1-15M, all + 6 entities interconnected. - id: DQ-02 name: Realistic Context score: 5 max: 5 passed: true - comment: Continental migration flows in millions — neutral, real-world scenario + comment: Continental migration flows in millions — realistic, neutral, comprehensible. - id: DQ-03 name: Appropriate Scale score: 4 max: 4 passed: true - comment: Values 1-15 million plausible for intercontinental migration + comment: Values 1-15M plausible for continental migration flows. code_quality: score: 10 max: 10 @@ -176,45 +185,48 @@ review: score: 3 max: 3 passed: true - comment: Linear flow with no functions or classes + comment: 'Linear flow: imports, data, geometry, plot, save. No functions or + classes.' - id: CQ-02 name: Reproducibility score: 2 max: 2 passed: true - comment: Fully deterministic hardcoded matrix + comment: Fully deterministic with hardcoded flow matrix. - id: CQ-03 name: Clean Imports score: 2 max: 2 passed: true - comment: All 4 imports used + comment: 'All imports used: matplotlib.patches, pyplot, numpy, Path.' - id: CQ-04 name: Code Elegance score: 2 max: 2 passed: true - comment: Smart pre-computation of chord positions, clean alpha formula + comment: Smart pre-computation of chord positions. Clean Bezier path construction. + Appropriate complexity. - id: CQ-05 name: Output & API score: 1 max: 1 passed: true - comment: Saves as plot.png, dpi=300, bbox_inches=tight + comment: Saves as plot.png with dpi=300, bbox_inches=tight. library_mastery: - score: 7 + score: 8 max: 10 items: - id: LM-01 name: Idiomatic Usage - score: 3 + score: 4 max: 5 passed: true - comment: Correct use of patches and Path API but very low-level approach + comment: Proper use of matplotlib low-level rendering API (fig/ax, add_patch) + — correct approach for custom chord diagram. - id: LM-02 name: Distinctive Features score: 4 max: 5 passed: true - comment: Bezier curves via Path CURVE4, mpatches.Wedge, PathPatch — distinctively - matplotlib + comment: Leverages Path with CURVE4 Bezier curves, mpatches.Wedge, PathPatch + — distinctive matplotlib geometry features.