From ab0868999f60e56b32631a9930d09cdf031e67b0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 26 Apr 2026 09:14:24 +0000 Subject: [PATCH 1/7] chore(pygal): add metadata for network-force-directed --- .../metadata/python/pygal.yaml | 202 ++---------------- 1 file changed, 13 insertions(+), 189 deletions(-) diff --git a/plots/network-force-directed/metadata/python/pygal.yaml b/plots/network-force-directed/metadata/python/pygal.yaml index a1425c0507..77a9cae3e0 100644 --- a/plots/network-force-directed/metadata/python/pygal.yaml +++ b/plots/network-force-directed/metadata/python/pygal.yaml @@ -1,197 +1,21 @@ +# Per-library metadata for pygal implementation of network-force-directed +# Auto-generated by impl-generate.yml + library: pygal +language: python specification_id: network-force-directed created: 2025-12-17 10:04:33+00:00 -updated: 2025-12-17 10:04:33+00:00 -generated_by: claude-opus-4-5-20251101 -workflow_run: 20298900805 +updated: '2026-04-26T09:14:24Z' +generated_by: claude-opus +workflow_run: 24952933179 issue: 990 -python_version: 3.13.11 +python_version: 3.14.4 library_version: 3.1.0 -preview_url: https://storage.googleapis.com/anyplot-images/plots/network-force-directed/pygal/plot.png -preview_html: https://storage.googleapis.com/anyplot-images/plots/network-force-directed/pygal/plot.html -quality_score: 92 -impl_tags: - dependencies: [] - techniques: - - html-export - patterns: - - data-generation - dataprep: [] - styling: [] +preview_url_light: https://storage.googleapis.com/anyplot-images/plots/network-force-directed/python/pygal/plot-light.png +preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/network-force-directed/python/pygal/plot-dark.png +preview_html_light: https://storage.googleapis.com/anyplot-images/plots/network-force-directed/python/pygal/plot-light.html +preview_html_dark: https://storage.googleapis.com/anyplot-images/plots/network-force-directed/python/pygal/plot-dark.html +quality_score: null review: strengths: [] weaknesses: [] - improvements: [] - image_description: 'The plot displays a force-directed network graph with 50 nodes - organized into 3 clearly visible communities. The title "network-force-directed - · pygal · pyplots.ai" is displayed at the top. Nodes are colored by community: - **blue** (Sales) cluster on the right side, **yellow** (Marketing) cluster in - the lower-center, and **red/coral** (Engineering) cluster in the upper-left. Gray - lines connect nodes representing edges/relationships. The communities are visually - separated with sparse bridge connections between them. A legend at the bottom - identifies the four series: "Connections", "Engineering", "Marketing", and "Sales". - The layout shows the force-directed algorithm successfully clustering related - nodes together.' - criteria_checklist: - visual_quality: - score: 32 - max: 35 - items: - - id: VQ-01 - name: Axis labels - score: 7 - max: 7 - passed: true - comment: Appropriately hidden (not applicable for network graphs) - - id: VQ-02 - name: No overlapping text - score: 6 - max: 6 - passed: true - comment: Clean layout, no text overlap - - id: VQ-03 - name: Color choice - score: 5 - max: 5 - passed: true - comment: Blue, yellow, red are distinguishable and colorblind-safe - - id: VQ-04 - name: Element clarity - score: 5 - max: 5 - passed: true - comment: Nodes are clearly visible with appropriate dot size (25) - - id: VQ-05 - name: Layout balance - score: 4 - max: 5 - passed: true - comment: Good proportions, communities well separated - - id: VQ-06 - name: Grid subtlety - score: 3 - max: 3 - passed: true - comment: Grid appropriately disabled for network visualization - - id: VQ-07 - name: Legend placement - score: 2 - max: 2 - passed: true - comment: Legend at bottom, does not obscure data - - id: VQ-08 - name: Image size - score: 0 - max: 2 - passed: true - comment: 4800x2700 specified but aspect ratio appears slightly off - spec_compliance: - score: 33 - max: 35 - items: - - id: SC-01 - name: Correct plot type - score: 10 - max: 10 - passed: true - comment: Force-directed network graph correctly implemented - - id: SC-02 - name: Data mapped correctly - score: 7 - max: 7 - passed: true - comment: Nodes and edges properly positioned via physics simulation - - id: SC-03 - name: Required features present - score: 7 - max: 7 - passed: true - comment: Shows communities, connections, force-directed layout - - id: SC-04 - name: Data range - score: 4 - max: 4 - passed: true - comment: All nodes visible with appropriate padding - - id: SC-05 - name: Legend accuracy - score: 2 - max: 4 - passed: true - comment: Legend shows series but could be more descriptive - - id: SC-06 - name: Title format - score: 3 - max: 3 - passed: true - comment: Uses `{spec-id} · {library} · pyplots.ai` format correctly - data_quality: - score: 14 - max: 15 - items: - - id: DQ-01 - name: Feature coverage - score: 5 - max: 6 - passed: true - comment: Shows communities, varying node degrees, bridge connections; node - size by degree mentioned in spec but not implemented - - id: DQ-02 - name: Realistic context - score: 5 - max: 5 - passed: true - comment: Social network with Engineering/Marketing/Sales teams is plausible - - id: DQ-03 - name: Appropriate scale - score: 4 - max: 4 - passed: true - comment: 50 nodes is appropriate, edge density is reasonable - code_quality: - score: 13 - max: 15 - items: - - id: CQ-01 - name: KISS structure - score: 4 - max: 4 - passed: true - comment: Sequential structure, no functions/classes - - id: CQ-02 - name: Reproducibility - score: 3 - max: 3 - passed: true - comment: Uses np.random.seed(42) - - id: CQ-03 - name: Library idioms - score: 3 - max: 3 - passed: true - comment: Proper pygal XY chart usage with Style - - id: CQ-04 - name: Clean imports - score: 2 - max: 2 - passed: true - comment: Only numpy, pygal, and Style imported - - id: CQ-05 - name: Helpful comments - score: 0 - max: 1 - passed: true - comment: Comments present but minimal - - id: CQ-06 - name: No deprecated API - score: 1 - max: 1 - passed: true - comment: Current pygal API used - - id: CQ-07 - name: Output correct - score: 0 - max: 1 - passed: true - comment: Saves plot.png but also saves plot.svg and plot.html (extra files) - verdict: APPROVED From d54f558ae05d66d52f2df7cb2d9299ae8c8d0450 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 26 Apr 2026 09:23:00 +0000 Subject: [PATCH 2/7] chore(pygal): update quality score 73 and review feedback for network-force-directed --- .../implementations/python/pygal.py | 6 +- .../metadata/python/pygal.yaml | 240 +++++++++++++++++- 2 files changed, 236 insertions(+), 10 deletions(-) diff --git a/plots/network-force-directed/implementations/python/pygal.py b/plots/network-force-directed/implementations/python/pygal.py index 1c2cb7e55c..ce7596561f 100644 --- a/plots/network-force-directed/implementations/python/pygal.py +++ b/plots/network-force-directed/implementations/python/pygal.py @@ -1,7 +1,7 @@ -""" pyplots.ai +""" anyplot.ai network-force-directed: Force-Directed Graph -Library: pygal 3.1.0 | Python 3.13.11 -Quality: 92/100 | Created: 2025-12-17 +Library: pygal 3.1.0 | Python 3.14.4 +Quality: 73/100 | Created: 2026-04-26 """ import numpy as np diff --git a/plots/network-force-directed/metadata/python/pygal.yaml b/plots/network-force-directed/metadata/python/pygal.yaml index 77a9cae3e0..77b1fb064a 100644 --- a/plots/network-force-directed/metadata/python/pygal.yaml +++ b/plots/network-force-directed/metadata/python/pygal.yaml @@ -1,11 +1,8 @@ -# Per-library metadata for pygal implementation of network-force-directed -# Auto-generated by impl-generate.yml - library: pygal language: python specification_id: network-force-directed created: 2025-12-17 10:04:33+00:00 -updated: '2026-04-26T09:14:24Z' +updated: '2026-04-26T09:23:00Z' generated_by: claude-opus workflow_run: 24952933179 issue: 990 @@ -15,7 +12,236 @@ preview_url_light: https://storage.googleapis.com/anyplot-images/plots/network-f preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/network-force-directed/python/pygal/plot-dark.png preview_html_light: https://storage.googleapis.com/anyplot-images/plots/network-force-directed/python/pygal/plot-light.html preview_html_dark: https://storage.googleapis.com/anyplot-images/plots/network-force-directed/python/pygal/plot-dark.html -quality_score: null +quality_score: 73 review: - strengths: [] - weaknesses: [] + strengths: + - Manual Fruchterman-Reingold layout algorithm produces clear community separation + - Good corporate social network data (Engineering/Marketing/Sales) — neutral and + realistic + - Clean linear code structure with reproducibility via np.random.seed(42) + - Removing axes/grid/labels is the correct design choice for a network graph + - Force-directed layout effectively tells a data story about departmental clusters + and bridge connections + weaknesses: + - 'No ANYPLOT_THEME support — background hardcoded to pure white instead of adapting + to #FAF8F1 (light) / #1A1A17 (dark)' + - 'Community colors use #306998 (Python Blue — explicitly forbidden), #FFD43B, #FF6B6B + instead of Okabe-Ito palette' + - Output files saved as plot.png/plot.html instead of plot-{THEME}.png/plot-{THEME}.html + - Title contains pyplots.ai instead of anyplot.ai + - First community should use Okabe-Ito position 1 (#009E73) as brand color + - Sales cluster has overlapping nodes due to high density — adjust repulsion strength + image_description: |- + Light render (plot-light.png): + Background: Warm off-white approximately #FAF8F1 — correct theme surface + Chrome: Title "network-force-directed · pygal · anyplot.ai" in dark text, readable; legend at bottom with small but legible labels + Data: Three community clusters — Engineering (blue, upper-left), Marketing (orange, lower-center), Sales (teal/green, right); gray edges; Sales cluster is dense with overlapping nodes + Legibility verdict: PASS — all text readable against light background; no light-on-light failures + + Dark render (plot-dark.png): + Background: Near-black approximately #1A1A17 — correct dark theme surface + Chrome: Title and legend text in light/white color; all readable against dark background; no dark-on-dark failures observed + Data: Colors identical to light render (blue Engineering, orange Marketing, teal/green Sales) — only chrome flipped as expected + Legibility verdict: PASS — all text readable against dark background + + NOTE: Significant discrepancy between images and source code. Images show warm backgrounds and Okabe-Ito-compatible colors, but python/pygal.py specifies background="white" (pure #FFFFFF), Python-palette colors (#306998/#FFD43B/#FF6B6B), and has no ANYPLOT_THEME support. The code is authoritative for compliance scoring. + criteria_checklist: + visual_quality: + score: 20 + max: 30 + items: + - id: VQ-01 + name: Text Legibility + score: 5 + max: 8 + passed: true + comment: Font sizes explicitly set; text readable in both renders; legend + dots small relative to 4800x2700 canvas + - id: VQ-02 + name: No Overlap + score: 4 + max: 6 + passed: true + comment: Sales cluster on right shows node overlap due to high density; Engineering + and Marketing clusters are clean + - id: VQ-03 + name: Element Visibility + score: 4 + max: 6 + passed: true + comment: Nodes and edges visible; Sales cluster density reduces individual + node readability + - id: VQ-04 + name: Color Accessibility + score: 2 + max: 2 + passed: true + comment: Three distinct community colors with good luminance contrast; not + relying on red-green + - id: VQ-05 + name: Layout & Canvas + score: 3 + max: 4 + passed: true + comment: Network occupies good canvas portion; some empty space in upper-left + and lower-right + - id: VQ-06 + name: Axis Labels & Title + score: 2 + max: 2 + passed: true + comment: Title present; no axis labels appropriate for network graph + - id: VQ-07 + name: Palette Compliance + score: 0 + max: 2 + passed: false + comment: 'Code uses #306998 (Python Blue, explicitly forbidden), #FFD43B, + #FF6B6B — not Okabe-Ito; background=white (pure #FFFFFF not #FAF8F1); no + ANYPLOT_THEME support; wrong output filenames' + design_excellence: + score: 12 + max: 20 + items: + - id: DE-01 + name: Aesthetic Sophistication + score: 4 + max: 8 + passed: true + comment: Clean network with community coloring; above generic defaults but + no exceptional polish + - id: DE-02 + name: Visual Refinement + score: 4 + max: 6 + passed: true + comment: No axes, no grid, no spines — well-suited for network graph; legend + at bottom appropriate + - id: DE-03 + name: Data Storytelling + score: 4 + max: 6 + passed: true + comment: Force-directed layout reveals three-community structure and sparse + bridge connections effectively + spec_compliance: + score: 13 + max: 15 + items: + - id: SC-01 + name: Plot Type + score: 5 + max: 5 + passed: true + comment: Correct force-directed graph with Fruchterman-Reingold physics simulation + - id: SC-02 + name: Required Features + score: 3 + max: 4 + passed: true + comment: Nodes with IDs, edges, community grouping; node size does not scale + by degree (optional per spec) + - id: SC-03 + name: Data Mapping + score: 3 + max: 3 + passed: true + comment: Network structure correctly mapped; communities spatially separated + by layout algorithm + - id: SC-04 + name: Title & Legend + score: 2 + max: 3 + passed: false + comment: Code title uses 'pyplots.ai' instead of 'anyplot.ai'; images show + correct format but code is authoritative + data_quality: + score: 14 + max: 15 + items: + - id: DQ-01 + name: Feature Coverage + score: 5 + max: 6 + passed: true + comment: Intra-community dense edges, sparse inter-community bridges, hub + nodes flagged in tooltips + - id: DQ-02 + name: Realistic Context + score: 5 + max: 5 + passed: true + comment: Corporate social network (Engineering/Marketing/Sales) — realistic + and neutral + - id: DQ-03 + name: Appropriate Scale + score: 4 + max: 4 + passed: true + comment: 50 nodes within spec's 20-200 range; edge density appropriate + code_quality: + score: 9 + max: 10 + items: + - id: CQ-01 + name: KISS Structure + score: 3 + max: 3 + passed: true + comment: 'Linear structure: imports, data, layout algorithm, plot, save; no + functions or classes' + - id: CQ-02 + name: Reproducibility + score: 2 + max: 2 + passed: true + comment: np.random.seed(42) set at top + - id: CQ-03 + name: Clean Imports + score: 2 + max: 2 + passed: true + comment: Only numpy and pygal imported, both used + - id: CQ-04 + name: Code Elegance + score: 2 + max: 2 + passed: true + comment: Manual FR implementation appropriate since pygal lacks native network + chart; clean and readable + - id: CQ-05 + name: Output & API + score: 0 + max: 1 + passed: false + comment: Saves as plot.png/plot.html instead of plot-{THEME}.png/plot-{THEME}.html; + no ANYPLOT_THEME support + library_mastery: + score: 5 + max: 10 + items: + - id: LM-01 + name: Idiomatic Usage + score: 3 + max: 5 + passed: true + comment: Correctly uses pygal.XY() with per-series stroke=True/False and show_dots + control; Style object used + - id: LM-02 + name: Distinctive Features + score: 2 + max: 5 + passed: false + comment: Uses legend_at_bottom with columns, per-series stroke control — pygal-specific + but not especially distinctive + verdict: REJECTED +impl_tags: + dependencies: [] + techniques: + - html-export + patterns: + - data-generation + - iteration-over-groups + dataprep: [] + styling: + - minimal-chrome From 80a3d40148312935157e20e73322150380cd57fd Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 26 Apr 2026 09:27:45 +0000 Subject: [PATCH 3/7] fix(pygal): repair feedback for network-force-directed - attempt 1/3 --- .../implementations/python/pygal.py | 125 +++++++++--------- 1 file changed, 60 insertions(+), 65 deletions(-) diff --git a/plots/network-force-directed/implementations/python/pygal.py b/plots/network-force-directed/implementations/python/pygal.py index ce7596561f..0e85e764af 100644 --- a/plots/network-force-directed/implementations/python/pygal.py +++ b/plots/network-force-directed/implementations/python/pygal.py @@ -1,23 +1,41 @@ -""" anyplot.ai +"""anyplot.ai network-force-directed: Force-Directed Graph Library: pygal 3.1.0 | Python 3.14.4 -Quality: 73/100 | Created: 2026-04-26 """ -import numpy as np -import pygal -from pygal.style import Style +import sys +from pathlib import Path -# Set seed for reproducibility +# Remove script directory from path to avoid name collision with pygal package +_script_dir = str(Path(__file__).parent) +sys.path = [p for p in sys.path if p != _script_dir] + +import os # noqa: E402 + +import numpy as np # noqa: E402 +import pygal # noqa: E402 +from pygal.style import Style # noqa: E402 + + +# Theme-adaptive tokens +THEME = os.getenv("ANYPLOT_THEME", "light") +PAGE_BG = "#FAF8F1" if THEME == "light" else "#1A1A17" +INK = "#1A1A17" if THEME == "light" else "#F0EFE8" +INK_SOFT = "#4A4A44" if THEME == "light" else "#B8B7B0" +INK_MUTED = "#6B6A63" if THEME == "light" else "#A8A79F" +EDGE_COLOR = "#9A988F" if THEME == "light" else "#5A5852" + +OKABE_ITO = ("#009E73", "#D55E00", "#0072B2", "#CC79A7", "#E69F00", "#56B4E9", "#F0E442") + +# Reproducibility np.random.seed(42) -# Data: A social network with 50 nodes in 3 communities +# Data: A corporate social network with 50 nodes in 3 departments # Demonstrates force-directed layout with clear community structure nodes = [] edges = [] -# Create 3 communities community_sizes = [18, 17, 15] # Total: 50 nodes community_names = ["Engineering", "Marketing", "Sales"] node_id = 0 @@ -50,18 +68,17 @@ bridge_edges = [(0, 18), (5, 20), (10, 25), (18, 35), (22, 40), (30, 45), (8, 38), (15, 48)] edges.extend(bridge_edges) -# Force-directed layout algorithm (Fruchterman-Reingold) +# Force-directed layout (Fruchterman-Reingold) n = len(nodes) positions = np.random.rand(n, 2) * 2 - 1 # Initial random positions -# Optimal distance parameter -k = 0.5 -iterations = 200 +k = 0.65 # Optimal distance — slightly larger to reduce dense-cluster overlap +iterations = 250 for iteration in range(iterations): displacement = np.zeros((n, 2)) - # Repulsive forces between all node pairs (nodes push apart) + # Repulsive forces between all node pairs for i in range(n): for j in range(i + 1, n): diff = positions[i] - positions[j] @@ -70,7 +87,7 @@ displacement[i] += repulsive_force displacement[j] -= repulsive_force - # Attractive forces along edges (connected nodes pull together) + # Attractive forces along edges for src, tgt in edges: diff = positions[src] - positions[tgt] dist = max(np.linalg.norm(diff), 0.01) @@ -78,85 +95,83 @@ displacement[src] -= attractive_force displacement[tgt] += attractive_force - # Apply displacement with cooling (decreasing temperature) + # Apply displacement with cooling temperature = 1 - iteration / iterations for i in range(n): disp_norm = np.linalg.norm(displacement[i]) if disp_norm > 0: - # Limit movement by temperature positions[i] += (displacement[i] / disp_norm) * min(disp_norm, 0.15 * temperature) -# Normalize positions to [1, 11] range for pygal (with padding) +# Normalize positions to a padded plotting range pos_min = positions.min(axis=0) pos_max = positions.max(axis=0) positions = (positions - pos_min) / (pos_max - pos_min + 1e-6) * 10 + 1 pos = {node["id"]: positions[i] for i, node in enumerate(nodes)} -# Calculate node degrees (number of connections) +# Node degrees (for tooltip context) degrees = {node["id"]: 0 for node in nodes} for src, tgt in edges: degrees[src] += 1 degrees[tgt] += 1 -# Community colors -community_colors = ["#306998", "#FFD43B", "#FF6B6B"] +# Style — first data series is the edge "Connections" (muted), then communities use Okabe-Ito 1..3 +community_colors = OKABE_ITO[: len(community_names)] +series_colors = (EDGE_COLOR,) + community_colors -# Custom style for the chart custom_style = Style( - background="white", - plot_background="white", - foreground="#333333", - foreground_strong="#333333", - foreground_subtle="#666666", - colors=("#AAAAAA",) + tuple(community_colors), + background=PAGE_BG, + plot_background=PAGE_BG, + foreground=INK, + foreground_strong=INK, + foreground_subtle=INK_MUTED, + colors=series_colors, title_font_size=72, label_font_size=40, major_label_font_size=36, - legend_font_size=40, + legend_font_size=44, value_font_size=32, stroke_width=2, - opacity=0.85, + opacity=0.9, opacity_hover=1.0, + tooltip_font_size=28, + font_family="DejaVu Sans, Helvetica, Arial, sans-serif", ) -# Create XY chart chart = pygal.XY( width=4800, height=2700, style=custom_style, - title="network-force-directed · pygal · pyplots.ai", + title="network-force-directed · pygal · anyplot.ai", show_legend=True, - x_title="", - y_title="", show_x_guides=False, show_y_guides=False, show_x_labels=False, show_y_labels=False, stroke=True, - dots_size=25, + dots_size=28, stroke_style={"width": 1.5, "linecap": "round"}, legend_at_bottom=True, legend_at_bottom_columns=4, + legend_box_size=36, + margin=80, range=(0, 12), xrange=(0, 12), ) -# Add edges as a single series with lines connecting pairs -# Each edge is represented as two points connected, with None to break between edges +# Edges as a single XY series with None breaks between segments edge_points = [] for src, tgt in edges: x1, y1 = pos[src] x2, y2 = pos[tgt] edge_points.append((x1, y1)) edge_points.append((x2, y2)) - edge_points.append(None) # Break the line for next edge + edge_points.append(None) chart.add("Connections", edge_points, stroke=True, show_dots=False, fill=False) -# Add nodes grouped by community +# Nodes grouped by community — pygal cycles colors per series after the edges series for comm_idx, comm_name in enumerate(community_names): comm_nodes = [node for node in nodes if node["community"] == comm_idx] - # Create points with labels for tooltips showing degree node_points = [] for node in comm_nodes: x, y = pos[node["id"]] @@ -167,29 +182,9 @@ node_points.append({"value": (x, y), "label": label}) chart.add(comm_name, node_points, stroke=False) -# Save outputs -chart.render_to_file("plot.svg") -chart.render_to_png("plot.png") - -# Also save HTML for interactive version -with open("plot.html", "w") as f: - f.write( - """ - - - network-force-directed · pygal · pyplots.ai - - - -
- - Force-directed network graph not supported - -
- -""" - ) +# Save outputs (theme-aware filenames) +chart.render_to_file(f"plot-{THEME}.svg") +chart.render_to_png(f"plot-{THEME}.png") + +with open(f"plot-{THEME}.html", "wb") as f: + f.write(chart.render()) From bbfbfda1a3436f5c435030edbc1a096a484ebe86 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 26 Apr 2026 09:33:37 +0000 Subject: [PATCH 4/7] chore(pygal): update quality score 81 and review feedback for network-force-directed --- .../implementations/python/pygal.py | 3 +- .../metadata/python/pygal.yaml | 204 ++++++++++-------- 2 files changed, 113 insertions(+), 94 deletions(-) diff --git a/plots/network-force-directed/implementations/python/pygal.py b/plots/network-force-directed/implementations/python/pygal.py index 0e85e764af..8ce61552a5 100644 --- a/plots/network-force-directed/implementations/python/pygal.py +++ b/plots/network-force-directed/implementations/python/pygal.py @@ -1,6 +1,7 @@ -"""anyplot.ai +""" anyplot.ai network-force-directed: Force-Directed Graph Library: pygal 3.1.0 | Python 3.14.4 +Quality: 81/100 | Created: 2026-04-26 """ import sys diff --git a/plots/network-force-directed/metadata/python/pygal.yaml b/plots/network-force-directed/metadata/python/pygal.yaml index 77b1fb064a..b37a976201 100644 --- a/plots/network-force-directed/metadata/python/pygal.yaml +++ b/plots/network-force-directed/metadata/python/pygal.yaml @@ -2,7 +2,7 @@ library: pygal language: python specification_id: network-force-directed created: 2025-12-17 10:04:33+00:00 -updated: '2026-04-26T09:23:00Z' +updated: '2026-04-26T09:33:37Z' generated_by: claude-opus workflow_run: 24952933179 issue: 990 @@ -12,93 +12,99 @@ preview_url_light: https://storage.googleapis.com/anyplot-images/plots/network-f preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/network-force-directed/python/pygal/plot-dark.png preview_html_light: https://storage.googleapis.com/anyplot-images/plots/network-force-directed/python/pygal/plot-light.html preview_html_dark: https://storage.googleapis.com/anyplot-images/plots/network-force-directed/python/pygal/plot-dark.html -quality_score: 73 +quality_score: 81 review: strengths: - - Manual Fruchterman-Reingold layout algorithm produces clear community separation - - Good corporate social network data (Engineering/Marketing/Sales) — neutral and - realistic - - Clean linear code structure with reproducibility via np.random.seed(42) - - Removing axes/grid/labels is the correct design choice for a network graph - - Force-directed layout effectively tells a data story about departmental clusters - and bridge connections + - Correct Fruchterman-Reingold force-directed physics simulation with 250 iterations, + cooling schedule, and proper repulsive/attractive forces producing a realistic + network layout + - 'Excellent theme adaptation: all chrome correctly flips between #FAF8F1/#1A1A17 + while Okabe-Ito data colors remain constant across both renders' + - Perfect code quality — clean KISS structure, reproducible with seed(42), correct + output files including interactive HTML + - Corporate department network dataset is realistic, neutral, and effectively demonstrates + community structure with bridge edges + - Interactive pygal HTML with degree-based node tooltips is a distinctive, library-native + feature weaknesses: - - 'No ANYPLOT_THEME support — background hardcoded to pure white instead of adapting - to #FAF8F1 (light) / #1A1A17 (dark)' - - 'Community colors use #306998 (Python Blue — explicitly forbidden), #FFD43B, #FF6B6B - instead of Okabe-Ito palette' - - Output files saved as plot.png/plot.html instead of plot-{THEME}.png/plot-{THEME}.html - - Title contains pyplots.ai instead of anyplot.ai - - First community should use Okabe-Ito position 1 (#009E73) as brand color - - Sales cluster has overlapping nodes due to high density — adjust repulsion strength + - 'First chart series (Connections/edges) uses neutral gray (#9A988F), breaking + the first-series = #009E73 rule — affects VQ-07. Consider restructuring color + assignment so Engineering gets position 1 in the Okabe-Ito cycle.' + - 'Canvas utilization ~55%: force-directed layout leaves significant empty space, + especially in lower-left. Expand node normalization spread or reduce chart range + from (0,12) to fill the canvas better.' + - Node size is uniform — degree-based scaling would improve visual sophistication + (DE-01) and spec feature coverage (SC-02). Hub nodes (degree >= 7) should be visually + larger in the static render, not just labeled in tooltips. + - dots_size=28 is slightly small for 50 nodes at 4800x2700px; 32-36 would improve + VQ-03. image_description: |- Light render (plot-light.png): - Background: Warm off-white approximately #FAF8F1 — correct theme surface - Chrome: Title "network-force-directed · pygal · anyplot.ai" in dark text, readable; legend at bottom with small but legible labels - Data: Three community clusters — Engineering (blue, upper-left), Marketing (orange, lower-center), Sales (teal/green, right); gray edges; Sales cluster is dense with overlapping nodes - Legibility verdict: PASS — all text readable against light background; no light-on-light failures + Background: Warm off-white (#FAF8F1) — correct, not pure white + Chrome: Title "network-force-directed · pygal · anyplot.ai" in dark text at top — fully readable. Legend at bottom with labels "Connections", "Engineering", "Marketing", "Sales" — readable. No axis labels (intentionally hidden for network graph). + Data: Three community clusters visible — green Engineering (right-center), orange Marketing (lower-left), blue Sales (upper-left). Gray edges connect nodes within and between communities. 50 nodes total. Canvas utilization ~55%, with empty space in lower-left. + Legibility verdict: PASS — all text is readable against the light background Dark render (plot-dark.png): - Background: Near-black approximately #1A1A17 — correct dark theme surface - Chrome: Title and legend text in light/white color; all readable against dark background; no dark-on-dark failures observed - Data: Colors identical to light render (blue Engineering, orange Marketing, teal/green Sales) — only chrome flipped as expected - Legibility verdict: PASS — all text readable against dark background - - NOTE: Significant discrepancy between images and source code. Images show warm backgrounds and Okabe-Ito-compatible colors, but python/pygal.py specifies background="white" (pure #FFFFFF), Python-palette colors (#306998/#FFD43B/#FF6B6B), and has no ANYPLOT_THEME support. The code is authoritative for compliance scoring. + Background: Near-black (#1A1A17) — correct, not pure black + Chrome: Title text is light-colored and readable against dark background. Legend text is light-colored. No dark-on-dark failures detected. + Data: Data colors are identical to light render — Engineering nodes remain #009E73 green, Marketing nodes remain #D55E00 orange, Sales nodes remain #0072B2 blue. Edge gray is slightly darker (#5A5852) but still subtly visible. Layout identical to light render. + Legibility verdict: PASS — all text is readable against the dark background; no chrome failures criteria_checklist: visual_quality: - score: 20 + score: 24 max: 30 items: - id: VQ-01 name: Text Legibility - score: 5 + score: 7 max: 8 passed: true - comment: Font sizes explicitly set; text readable in both renders; legend - dots small relative to 4800x2700 canvas + comment: Font sizes explicitly set (title=72, legend=44, label=40, major_label=36). + All readable in both themes. Minor deduction for tooltip_font_size=28. - id: VQ-02 name: No Overlap - score: 4 + score: 5 max: 6 passed: true - comment: Sales cluster on right shows node overlap due to high density; Engineering - and Marketing clusters are clean + comment: Mostly clean. Engineering cluster slightly dense but not severely + overlapping. - id: VQ-03 name: Element Visibility - score: 4 + score: 5 max: 6 passed: true - comment: Nodes and edges visible; Sales cluster density reduces individual - node readability + comment: dots_size=28 at 4800x2700px is visible but on the smaller side. Acceptable + for 50 nodes. - id: VQ-04 name: Color Accessibility score: 2 max: 2 passed: true - comment: Three distinct community colors with good luminance contrast; not - relying on red-green + comment: Okabe-Ito palette, CVD-safe, good contrast between communities and + gray edges. - id: VQ-05 name: Layout & Canvas - score: 3 + score: 2 max: 4 - passed: true - comment: Network occupies good canvas portion; some empty space in upper-left - and lower-right + passed: false + comment: Canvas utilization ~55%. Notable empty space in lower-left. Network + spread does not fill the 4800x2700 canvas well. - id: VQ-06 name: Axis Labels & Title score: 2 max: 2 passed: true - comment: Title present; no axis labels appropriate for network graph + comment: Title correctly formatted. Axis labels intentionally hidden (appropriate + for network graph). - id: VQ-07 name: Palette Compliance - score: 0 + score: 1 max: 2 passed: false - comment: 'Code uses #306998 (Python Blue, explicitly forbidden), #FFD43B, - #FF6B6B — not Okabe-Ito; background=white (pure #FFFFFF not #FAF8F1); no - ANYPLOT_THEME support; wrong output filenames' + comment: 'Partial. First series (Connections) uses gray #9A988F, not #009E73. + First categorical community (Engineering) correctly uses #009E73. Backgrounds + are correct (#FAF8F1/#1A1A17). Chrome is theme-correct.' design_excellence: score: 12 max: 20 @@ -107,25 +113,27 @@ review: name: Aesthetic Sophistication score: 4 max: 8 - passed: true - comment: Clean network with community coloring; above generic defaults but - no exceptional polish + passed: false + comment: Well-configured with Okabe-Ito and theme-adaptive styling. All nodes + same size regardless of degree — hub nodes not visually distinguished. Not + exceptional. - id: DE-02 name: Visual Refinement score: 4 max: 6 - passed: true - comment: No axes, no grid, no spines — well-suited for network graph; legend - at bottom appropriate + passed: false + comment: Axes hidden (appropriate), grid disabled, margins 80px. Clean chrome. + No spines visible. Some refinement evident but could push further. - id: DE-03 name: Data Storytelling score: 4 max: 6 - passed: true - comment: Force-directed layout reveals three-community structure and sparse - bridge connections effectively + passed: false + comment: Three distinct community clusters with bridges tell connectivity + story naturally. Color coding by department creates clear visual grouping. + Hub nodes only labeled in tooltips, not visually distinct in static render. spec_compliance: - score: 13 + score: 14 max: 15 items: - id: SC-01 @@ -133,28 +141,30 @@ review: score: 5 max: 5 passed: true - comment: Correct force-directed graph with Fruchterman-Reingold physics simulation + comment: Correct force-directed graph with full Fruchterman-Reingold physics + simulation including cooling. - id: SC-02 name: Required Features score: 3 max: 4 - passed: true - comment: Nodes with IDs, edges, community grouping; node size does not scale - by degree (optional per spec) + passed: false + comment: 'Community structure, edges, force-directed layout, inter-community + bridges all present. Missing: node size scaling by degree, edge thickness + variation.' - id: SC-03 name: Data Mapping score: 3 max: 3 passed: true - comment: Network structure correctly mapped; communities spatially separated - by layout algorithm + comment: Nodes placed by force-directed positions, edges correctly drawn between + source/target pairs. - id: SC-04 name: Title & Legend - score: 2 + score: 3 max: 3 - passed: false - comment: Code title uses 'pyplots.ai' instead of 'anyplot.ai'; images show - correct format but code is authoritative + passed: true + comment: Title 'network-force-directed · pygal · anyplot.ai' correct. Legend + labels match data. data_quality: score: 14 max: 15 @@ -163,24 +173,26 @@ review: name: Feature Coverage score: 5 max: 6 - passed: true - comment: Intra-community dense edges, sparse inter-community bridges, hub - nodes flagged in tooltips + passed: false + comment: 'Shows community structure (3 groups), intra-community dense connectivity + (~30%), inter-community sparse bridges (8 edges), 50 nodes. Missing: visual + degree variation, edge weight differences.' - id: DQ-02 name: Realistic Context score: 5 max: 5 passed: true - comment: Corporate social network (Engineering/Marketing/Sales) — realistic - and neutral + comment: Corporate social network with Engineering, Marketing, Sales departments. + Real-world, neutral, comprehensible. - id: DQ-03 name: Appropriate Scale score: 4 max: 4 passed: true - comment: 50 nodes within spec's 20-200 range; edge density appropriate + comment: 50 nodes, 30% intra-community edge probability, 8 bridge edges. Realistic + for force-directed network. code_quality: - score: 9 + score: 10 max: 10 items: - id: CQ-01 @@ -188,60 +200,66 @@ review: score: 3 max: 3 passed: true - comment: 'Linear structure: imports, data, layout algorithm, plot, save; no - functions or classes' + comment: 'Clean linear flow: imports, data generation, force-directed layout, + normalization, chart creation, save. No classes or functions.' - id: CQ-02 name: Reproducibility score: 2 max: 2 passed: true - comment: np.random.seed(42) set at top + comment: np.random.seed(42) set before data generation. - id: CQ-03 name: Clean Imports score: 2 max: 2 passed: true - comment: Only numpy and pygal imported, both used + comment: sys, Path, os, numpy, pygal, Style — all used. noqa comments are + necessary for sys.path manipulation. - id: CQ-04 name: Code Elegance score: 2 max: 2 passed: true - comment: Manual FR implementation appropriate since pygal lacks native network - chart; clean and readable + comment: O(n^2) Fruchterman-Reingold is the standard algorithm. Code is clean + and Pythonic. None-break technique for XY edges is correct pygal idiom. - id: CQ-05 name: Output & API - score: 0 + score: 1 max: 1 - passed: false - comment: Saves as plot.png/plot.html instead of plot-{THEME}.png/plot-{THEME}.html; - no ANYPLOT_THEME support + passed: true + comment: Saves plot-{THEME}.png, .svg, and .html. Correct for pygal as interactive + library. library_mastery: - score: 5 + score: 7 max: 10 items: - id: LM-01 name: Idiomatic Usage - score: 3 + score: 4 max: 5 passed: true - comment: Correctly uses pygal.XY() with per-series stroke=True/False and show_dots - control; Style object used + comment: Uses pygal.XY with stroke for edges and dots for nodes. Style object + carries all theme tokens. None-break technique for line segments is idiomatic + pygal approach. - id: LM-02 name: Distinctive Features - score: 2 + score: 3 max: 5 passed: false - comment: Uses legend_at_bottom with columns, per-series stroke control — pygal-specific - but not especially distinctive + comment: Interactive HTML with per-node tooltips showing degree and hub status + is pygal-distinctive. XY None-break for edges is creative. But it is a workaround + rather than a built-in network feature. verdict: REJECTED impl_tags: dependencies: [] techniques: + - force-directed-layout + - hover-tooltips - html-export patterns: - data-generation - iteration-over-groups - dataprep: [] + dataprep: + - normalization styling: - minimal-chrome From 641ff09bad2cd684cfeb55e06fb7763fa5daec86 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 26 Apr 2026 09:52:58 +0000 Subject: [PATCH 5/7] chore(pygal): update quality score 84 and review feedback for network-force-directed --- .../implementations/python/pygal.py | 2 +- .../metadata/python/pygal.yaml | 207 +++++++++--------- 2 files changed, 102 insertions(+), 107 deletions(-) diff --git a/plots/network-force-directed/implementations/python/pygal.py b/plots/network-force-directed/implementations/python/pygal.py index 8ce61552a5..47d2e8397e 100644 --- a/plots/network-force-directed/implementations/python/pygal.py +++ b/plots/network-force-directed/implementations/python/pygal.py @@ -1,7 +1,7 @@ """ anyplot.ai network-force-directed: Force-Directed Graph Library: pygal 3.1.0 | Python 3.14.4 -Quality: 81/100 | Created: 2026-04-26 +Quality: 84/100 | Created: 2026-04-26 """ import sys diff --git a/plots/network-force-directed/metadata/python/pygal.yaml b/plots/network-force-directed/metadata/python/pygal.yaml index b37a976201..1c05febcbd 100644 --- a/plots/network-force-directed/metadata/python/pygal.yaml +++ b/plots/network-force-directed/metadata/python/pygal.yaml @@ -2,7 +2,7 @@ library: pygal language: python specification_id: network-force-directed created: 2025-12-17 10:04:33+00:00 -updated: '2026-04-26T09:33:37Z' +updated: '2026-04-26T09:52:57Z' generated_by: claude-opus workflow_run: 24952933179 issue: 990 @@ -12,128 +12,128 @@ preview_url_light: https://storage.googleapis.com/anyplot-images/plots/network-f preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/network-force-directed/python/pygal/plot-dark.png preview_html_light: https://storage.googleapis.com/anyplot-images/plots/network-force-directed/python/pygal/plot-light.html preview_html_dark: https://storage.googleapis.com/anyplot-images/plots/network-force-directed/python/pygal/plot-dark.html -quality_score: 81 +quality_score: 84 review: strengths: - - Correct Fruchterman-Reingold force-directed physics simulation with 250 iterations, - cooling schedule, and proper repulsive/attractive forces producing a realistic - network layout - - 'Excellent theme adaptation: all chrome correctly flips between #FAF8F1/#1A1A17 - while Okabe-Ito data colors remain constant across both renders' - - Perfect code quality — clean KISS structure, reproducible with seed(42), correct - output files including interactive HTML - - Corporate department network dataset is realistic, neutral, and effectively demonstrates - community structure with bridge edges - - Interactive pygal HTML with degree-based node tooltips is a distinctive, library-native - feature + - Force-directed layout using Fruchterman-Reingold algorithm with proper cooling, + resulting in well-separated community clusters + - Theme-adaptive styling correctly applied in both light and dark renders with correct + background colors (#FAF8F1/#1A1A17) + - Interactive pygal tooltips with node degree and hub status information fully leveraged + - Clean Okabe-Ito community colors (Engineering=#009E73, Marketing=#D55E00, Sales=#0072B2) + with muted edge styling + - Reproducible with np.random.seed(42) and correct output files (PNG + SVG + HTML) weaknesses: - - 'First chart series (Connections/edges) uses neutral gray (#9A988F), breaking - the first-series = #009E73 rule — affects VQ-07. Consider restructuring color - assignment so Engineering gets position 1 in the Okabe-Ito cycle.' - - 'Canvas utilization ~55%: force-directed layout leaves significant empty space, - especially in lower-left. Expand node normalization spread or reduce chart range - from (0,12) to fill the canvas better.' - - Node size is uniform — degree-based scaling would improve visual sophistication - (DE-01) and spec feature coverage (SC-02). Hub nodes (degree >= 7) should be visually - larger in the static render, not just labeled in tooltips. - - dots_size=28 is slightly small for 50 nodes at 4800x2700px; 32-36 would improve - VQ-03. + - 'First chart series is the edge/Connections series using muted gray rather than + #009E73 — technically violates first-series=green rule (minor, edges as structural + element is the correct design choice)' + - Some node overlap in dense cluster areas (Engineering right cluster, Sales top-left + cluster) due to uniform node sizing + - Node size does not scale by degree — degree information is only available via + tooltip, missing a visual encoding opportunity + - DE-02 visual refinement is functional but not exceptional — legend box styling + and overall polish could be higher image_description: |- Light render (plot-light.png): - Background: Warm off-white (#FAF8F1) — correct, not pure white - Chrome: Title "network-force-directed · pygal · anyplot.ai" in dark text at top — fully readable. Legend at bottom with labels "Connections", "Engineering", "Marketing", "Sales" — readable. No axis labels (intentionally hidden for network graph). - Data: Three community clusters visible — green Engineering (right-center), orange Marketing (lower-left), blue Sales (upper-left). Gray edges connect nodes within and between communities. 50 nodes total. Canvas utilization ~55%, with empty space in lower-left. - Legibility verdict: PASS — all text is readable against the light background + Background: Warm off-white (#FAF8F1) - correctly applied, not pure white. + Chrome: Title "network-force-directed · pygal · anyplot.ai" rendered in dark ink, clearly readable at top. No axis labels or tick labels (intentional for network graph). Legend at bottom shows Engineering (green square), Marketing (orange square), Sales (blue square), Connections (gray square) — all labels clearly readable in dark text on light background. + Data: Three distinct community clusters visible — Engineering (teal #009E73, right side), Marketing (vermillion #D55E00, bottom center), Sales (blue #0072B2, top left). Edge/connection lines rendered as muted gray (#9A988F), appropriately subtle. Node sizes are uniform (dots_size=28 global parameter). Bridge edges between clusters are clearly visible. + Legibility verdict: PASS Dark render (plot-dark.png): - Background: Near-black (#1A1A17) — correct, not pure black - Chrome: Title text is light-colored and readable against dark background. Legend text is light-colored. No dark-on-dark failures detected. - Data: Data colors are identical to light render — Engineering nodes remain #009E73 green, Marketing nodes remain #D55E00 orange, Sales nodes remain #0072B2 blue. Edge gray is slightly darker (#5A5852) but still subtly visible. Layout identical to light render. - Legibility verdict: PASS — all text is readable against the dark background; no chrome failures + Background: Warm near-black (#1A1A17) - correctly applied, not pure black. + Chrome: Title in light/off-white text clearly visible against dark background. Legend labels (Engineering, Marketing, Sales, Connections) rendered in light text on dark background — fully readable, no dark-on-dark issues. No axis labels or tick labels present. + Data: Node colors identical to light render — Engineering (#009E73 teal), Marketing (#D55E00 orange), Sales (#0072B2 blue). Edge lines rendered as darker muted gray (#5A5852), subtler on dark background but still visible. Community cluster separation is clearly maintained. Brand green #009E73 remains visible on the dark surface. + Legibility verdict: PASS criteria_checklist: visual_quality: - score: 24 + score: 25 max: 30 items: - id: VQ-01 name: Text Legibility - score: 7 + score: 8 max: 8 passed: true - comment: Font sizes explicitly set (title=72, legend=44, label=40, major_label=36). - All readable in both themes. Minor deduction for tooltip_font_size=28. + comment: All font sizes explicitly set in Style object (title_font_size=72, + label_font_size=40, major_label_font_size=36, legend_font_size=44). Title + and legend text clearly readable in both themes. - id: VQ-02 name: No Overlap - score: 5 + score: 4 max: 6 passed: true - comment: Mostly clean. Engineering cluster slightly dense but not severely - overlapping. + comment: Some node overlap in dense cluster areas (Engineering right cluster, + Sales top-left cluster) due to uniform node sizing and force-directed layout + density. - id: VQ-03 name: Element Visibility score: 5 max: 6 passed: true - comment: dots_size=28 at 4800x2700px is visible but on the smaller side. Acceptable - for 50 nodes. + comment: Nodes and edges clearly visible. dots_size=28 appropriate for canvas + size. Slight deduction for missing degree-based size scaling. - id: VQ-04 name: Color Accessibility score: 2 max: 2 passed: true - comment: Okabe-Ito palette, CVD-safe, good contrast between communities and - gray edges. + comment: Okabe-Ito palette CVD-safe. Three communities distinguishable by + hue and luminance. opacity=0.9 appropriate. - id: VQ-05 name: Layout & Canvas - score: 2 + score: 3 max: 4 - passed: false - comment: Canvas utilization ~55%. Notable empty space in lower-left. Network - spread does not fill the 4800x2700 canvas well. + passed: true + comment: Good canvas utilization (~70%). Legend at bottom. Force-directed + layout leaves some empty center-right space due to Engineering cluster being + pushed right. - id: VQ-06 name: Axis Labels & Title score: 2 max: 2 passed: true - comment: Title correctly formatted. Axis labels intentionally hidden (appropriate - for network graph). + comment: 'Title format correct: ''network-force-directed · pygal · anyplot.ai''. + No axis labels — appropriate for force-directed network graph where XY coordinates + have no semantic meaning.' - id: VQ-07 name: Palette Compliance score: 1 max: 2 - passed: false - comment: 'Partial. First series (Connections) uses gray #9A988F, not #009E73. - First categorical community (Engineering) correctly uses #009E73. Backgrounds - are correct (#FAF8F1/#1A1A17). Chrome is theme-correct.' + passed: true + comment: 'Backgrounds correct (#FAF8F1 light, #1A1A17 dark). Community colors + follow Okabe-Ito in order. Chrome theme-correct in both renders. Partial + deduction: first chart series (Connections/edges) uses muted gray rather + than #009E73, technically violating first-series rule despite being semantically + correct for edge rendering.' design_excellence: - score: 12 + score: 13 max: 20 items: - id: DE-01 name: Aesthetic Sophistication - score: 4 + score: 5 max: 8 - passed: false - comment: Well-configured with Okabe-Ito and theme-adaptive styling. All nodes - same size regardless of degree — hub nodes not visually distinguished. Not - exceptional. + passed: true + comment: Professional network graph appearance. Thoughtful edge/node color + separation. Theme-adaptive styling. Above configured default but not publication-exceptional. - id: DE-02 name: Visual Refinement score: 4 max: 6 - passed: false - comment: Axes hidden (appropriate), grid disabled, margins 80px. Clean chrome. - No spines visible. Some refinement evident but could push further. + passed: true + comment: Axes and grid guides appropriately hidden. Legend at bottom. Good + margins. Clean network layout. Functional refinement for network graph type. - id: DE-03 name: Data Storytelling score: 4 max: 6 - passed: false - comment: Three distinct community clusters with bridges tell connectivity - story naturally. Color coding by department creates clear visual grouping. - Hub nodes only labeled in tooltips, not visually distinct in static render. + passed: true + comment: Three community clusters with bridge edges tell a clear organizational + network story. Community separation through color creates immediate visual + insight. Hub nodes labeled in tooltips. spec_compliance: - score: 14 + score: 15 max: 15 items: - id: SC-01 @@ -141,30 +141,29 @@ review: score: 5 max: 5 passed: true - comment: Correct force-directed graph with full Fruchterman-Reingold physics - simulation including cooling. + comment: Force-directed graph with Fruchterman-Reingold physics simulation. + Correct node/edge structure. - id: SC-02 name: Required Features - score: 3 + score: 4 max: 4 - passed: false - comment: 'Community structure, edges, force-directed layout, inter-community - bridges all present. Missing: node size scaling by degree, edge thickness - variation.' + passed: true + comment: Nodes with unique IDs, edges, force-directed layout, community structure + — all present. - id: SC-03 name: Data Mapping score: 3 max: 3 passed: true - comment: Nodes placed by force-directed positions, edges correctly drawn between - source/target pairs. + comment: Position mapped to force-directed coordinates. Communities mapped + to Okabe-Ito colors. Edges correctly drawn between node positions. - id: SC-04 name: Title & Legend score: 3 max: 3 passed: true - comment: Title 'network-force-directed · pygal · anyplot.ai' correct. Legend - labels match data. + comment: 'Title: ''network-force-directed · pygal · anyplot.ai'' correct. + Legend: Engineering, Marketing, Sales, Connections — all correctly labeled.' data_quality: score: 14 max: 15 @@ -173,24 +172,24 @@ review: name: Feature Coverage score: 5 max: 6 - passed: false - comment: 'Shows community structure (3 groups), intra-community dense connectivity - (~30%), inter-community sparse bridges (8 edges), 50 nodes. Missing: visual - degree variation, edge weight differences.' + passed: true + comment: 'Shows intra-community edges, inter-community bridge edges, community + clustering, hub nodes labeled in tooltips. Missing: visual degree-based + node sizing.' - id: DQ-02 name: Realistic Context score: 5 max: 5 passed: true - comment: Corporate social network with Engineering, Marketing, Sales departments. - Real-world, neutral, comprehensible. + comment: Corporate social network (Engineering/Marketing/Sales departments) + — realistic, neutral, comprehensible scenario. - id: DQ-03 name: Appropriate Scale score: 4 max: 4 passed: true - comment: 50 nodes, 30% intra-community edge probability, 8 bridge edges. Realistic - for force-directed network. + comment: 50 nodes, 3 communities (18/17/15 nodes), ~80+ edges. Appropriate + scale for force-directed network visualization. code_quality: score: 10 max: 10 @@ -200,8 +199,8 @@ review: score: 3 max: 3 passed: true - comment: 'Clean linear flow: imports, data generation, force-directed layout, - normalization, chart creation, save. No classes or functions.' + comment: 'Clear procedural structure: imports → constants → data generation + → layout → styling → chart → save. No functions or classes.' - id: CQ-02 name: Reproducibility score: 2 @@ -213,22 +212,20 @@ review: score: 2 max: 2 passed: true - comment: sys, Path, os, numpy, pygal, Style — all used. noqa comments are - necessary for sys.path manipulation. + comment: All imports used. sys/Path workaround for name collision is explained. - id: CQ-04 name: Code Elegance score: 2 max: 2 passed: true - comment: O(n^2) Fruchterman-Reingold is the standard algorithm. Code is clean - and Pythonic. None-break technique for XY edges is correct pygal idiom. + comment: Clean Pythonic code. FR algorithm well-structured. No over-engineering. - id: CQ-05 name: Output & API score: 1 max: 1 passed: true - comment: Saves plot-{THEME}.png, .svg, and .html. Correct for pygal as interactive - library. + comment: Saves plot-{THEME}.svg, plot-{THEME}.png, plot-{THEME}.html. Current + pygal API used. library_mastery: score: 7 max: 10 @@ -238,28 +235,26 @@ review: score: 4 max: 5 passed: true - comment: Uses pygal.XY with stroke for edges and dots for nodes. Style object - carries all theme tokens. None-break technique for line segments is idiomatic - pygal approach. + comment: Uses pygal.XY with Style object, series-based structure, interactive + tooltip labels. Correct stroke/show_dots per series. Good idiomatic usage. - id: LM-02 name: Distinctive Features score: 3 max: 5 - passed: false - comment: Interactive HTML with per-node tooltips showing degree and hub status - is pygal-distinctive. XY None-break for edges is creative. But it is a workaround - rather than a built-in network feature. - verdict: REJECTED + passed: true + comment: Interactive tooltips with node info (degree, hub status), HTML output + for interactive chart, None-break technique for edge line series — distinctive + pygal features utilized. + verdict: APPROVED impl_tags: dependencies: [] techniques: - - force-directed-layout - - hover-tooltips - html-export + - hover-tooltips patterns: - data-generation - iteration-over-groups - dataprep: - - normalization + dataprep: [] styling: - minimal-chrome + - alpha-blending From 63387cb3fab15451c3dd3a9a65c5f0bd1a0cad52 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 26 Apr 2026 09:57:08 +0000 Subject: [PATCH 6/7] fix(pygal): address review feedback for network-force-directed Attempt 3/3 - fixes based on AI review: - Per-point dot radius scales with node degree (addresses VQ-03, DQ-01) - Increased FR k=0.95 and iterations=320 (addresses VQ-02 cluster overlap) --- .../implementations/python/pygal.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/plots/network-force-directed/implementations/python/pygal.py b/plots/network-force-directed/implementations/python/pygal.py index 47d2e8397e..d5f0c35f8f 100644 --- a/plots/network-force-directed/implementations/python/pygal.py +++ b/plots/network-force-directed/implementations/python/pygal.py @@ -1,4 +1,4 @@ -""" anyplot.ai +"""anyplot.ai network-force-directed: Force-Directed Graph Library: pygal 3.1.0 | Python 3.14.4 Quality: 84/100 | Created: 2026-04-26 @@ -73,8 +73,8 @@ n = len(nodes) positions = np.random.rand(n, 2) * 2 - 1 # Initial random positions -k = 0.65 # Optimal distance — slightly larger to reduce dense-cluster overlap -iterations = 250 +k = 0.95 # Optimal distance — larger to reduce dense-cluster node overlap +iterations = 320 for iteration in range(iterations): displacement = np.zeros((n, 2)) @@ -170,17 +170,21 @@ chart.add("Connections", edge_points, stroke=True, show_dots=False, fill=False) -# Nodes grouped by community — pygal cycles colors per series after the edges series +# Nodes grouped by community — radius scales with node degree (visual encoding) +# pygal supports per-point SVG attribute overrides via the "node" dict +max_degree = max(degrees.values()) +min_radius, max_radius = 18, 52 for comm_idx, comm_name in enumerate(community_names): comm_nodes = [node for node in nodes if node["community"] == comm_idx] node_points = [] for node in comm_nodes: x, y = pos[node["id"]] degree = degrees[node["id"]] + radius = min_radius + (max_radius - min_radius) * (degree / max_degree) label = f"Node {node['id']} | {degree} connections" if degree >= 7: label += " (Hub)" - node_points.append({"value": (x, y), "label": label}) + node_points.append({"value": (x, y), "label": label, "node": {"r": round(radius, 1)}}) chart.add(comm_name, node_points, stroke=False) # Save outputs (theme-aware filenames) From 2813e5790fa81c3abcb9ff31b3d754e2ff05409c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 26 Apr 2026 10:03:30 +0000 Subject: [PATCH 7/7] chore(pygal): update quality score 83 and review feedback for network-force-directed --- .../implementations/python/pygal.py | 4 +- .../metadata/python/pygal.yaml | 164 ++++++++---------- 2 files changed, 76 insertions(+), 92 deletions(-) diff --git a/plots/network-force-directed/implementations/python/pygal.py b/plots/network-force-directed/implementations/python/pygal.py index d5f0c35f8f..69132a7ffd 100644 --- a/plots/network-force-directed/implementations/python/pygal.py +++ b/plots/network-force-directed/implementations/python/pygal.py @@ -1,7 +1,7 @@ -"""anyplot.ai +""" anyplot.ai network-force-directed: Force-Directed Graph Library: pygal 3.1.0 | Python 3.14.4 -Quality: 84/100 | Created: 2026-04-26 +Quality: 83/100 | Created: 2026-04-26 """ import sys diff --git a/plots/network-force-directed/metadata/python/pygal.yaml b/plots/network-force-directed/metadata/python/pygal.yaml index 1c05febcbd..81658bfc3e 100644 --- a/plots/network-force-directed/metadata/python/pygal.yaml +++ b/plots/network-force-directed/metadata/python/pygal.yaml @@ -2,7 +2,7 @@ library: pygal language: python specification_id: network-force-directed created: 2025-12-17 10:04:33+00:00 -updated: '2026-04-26T09:52:57Z' +updated: '2026-04-26T10:03:29Z' generated_by: claude-opus workflow_run: 24952933179 issue: 990 @@ -12,38 +12,38 @@ preview_url_light: https://storage.googleapis.com/anyplot-images/plots/network-f preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/network-force-directed/python/pygal/plot-dark.png preview_html_light: https://storage.googleapis.com/anyplot-images/plots/network-force-directed/python/pygal/plot-light.html preview_html_dark: https://storage.googleapis.com/anyplot-images/plots/network-force-directed/python/pygal/plot-dark.html -quality_score: 84 +quality_score: 83 review: strengths: - - Force-directed layout using Fruchterman-Reingold algorithm with proper cooling, - resulting in well-separated community clusters - - Theme-adaptive styling correctly applied in both light and dark renders with correct - background colors (#FAF8F1/#1A1A17) - - Interactive pygal tooltips with node degree and hub status information fully leveraged - - Clean Okabe-Ito community colors (Engineering=#009E73, Marketing=#D55E00, Sales=#0072B2) - with muted edge styling - - Reproducible with np.random.seed(42) and correct output files (PNG + SVG + HTML) + - Complete Fruchterman-Reingold force-directed layout from scratch with no external + graph library + - 'Degree-based node sizing using pygal per-point SVG attribute overrides ({"node": + {"r": ...}}) — distinctive pygal feature' + - Three-community corporate social network (Engineering/Marketing/Sales) — realistic, + neutral scenario + - Full theme adaptation in both renders; all token assignments (background, foreground, + foreground_subtle) correctly derived from ANYPLOT_THEME + - 'Perfect code quality: seed set, clean imports, linear structure, appropriate + complexity; full output (PNG + SVG + HTML)' weaknesses: - - 'First chart series is the edge/Connections series using muted gray rather than - #009E73 — technically violates first-series=green rule (minor, edges as structural - element is the correct design choice)' - - Some node overlap in dense cluster areas (Engineering right cluster, Sales top-left - cluster) due to uniform node sizing - - Node size does not scale by degree — degree information is only available via - tooltip, missing a visual encoding opportunity - - DE-02 visual refinement is functional but not exceptional — legend box styling - and overall polish could be higher + - 'First pygal series Connections uses EDGE_COLOR (#9A988F light / #5A5852 dark) + rather than #009E73 — palette position 1 is not the brand green; reorder series + so Engineering comes first' + - Some node crowding in dense Engineering and Marketing clusters; increase repulsion + constant k from 0.95 to 1.1 for better node separation + - Legend font appears small relative to canvas at rendered scale despite legend_font_size=44 + being set image_description: |- Light render (plot-light.png): - Background: Warm off-white (#FAF8F1) - correctly applied, not pure white. - Chrome: Title "network-force-directed · pygal · anyplot.ai" rendered in dark ink, clearly readable at top. No axis labels or tick labels (intentional for network graph). Legend at bottom shows Engineering (green square), Marketing (orange square), Sales (blue square), Connections (gray square) — all labels clearly readable in dark text on light background. - Data: Three distinct community clusters visible — Engineering (teal #009E73, right side), Marketing (vermillion #D55E00, bottom center), Sales (blue #0072B2, top left). Edge/connection lines rendered as muted gray (#9A988F), appropriately subtle. Node sizes are uniform (dots_size=28 global parameter). Bridge edges between clusters are clearly visible. + Background: Warm off-white (#FAF8F1) — correct theme surface + Chrome: Title "network-force-directed · pygal · anyplot.ai" in dark text at top center — readable. No axis labels (appropriate for network graph). Legend at bottom with four entries (Connections, Engineering, Marketing, Sales) in dark text — readable. + Data: Three community clusters: Engineering (teal #009E73, right side), Marketing (orange #D55E00, lower-left), Sales (blue #0072B2, upper-center). Edges as light gray lines (#9A988F). Node sizes vary by degree — hub nodes noticeably larger. Legibility verdict: PASS Dark render (plot-dark.png): - Background: Warm near-black (#1A1A17) - correctly applied, not pure black. - Chrome: Title in light/off-white text clearly visible against dark background. Legend labels (Engineering, Marketing, Sales, Connections) rendered in light text on dark background — fully readable, no dark-on-dark issues. No axis labels or tick labels present. - Data: Node colors identical to light render — Engineering (#009E73 teal), Marketing (#D55E00 orange), Sales (#0072B2 blue). Edge lines rendered as darker muted gray (#5A5852), subtler on dark background but still visible. Community cluster separation is clearly maintained. Brand green #009E73 remains visible on the dark surface. + Background: Near-black (#1A1A17) — correct theme surface + Chrome: Title in light off-white text at top center — clearly readable. Legend at bottom in light-colored text — readable. No dark-on-dark text issues detected. + Data: Community colors identical to light render — Engineering green, Marketing orange, Sales blue. Edges appear as lighter gray on dark background. Node sizing preserved. Legibility verdict: PASS criteria_checklist: visual_quality: @@ -52,60 +52,52 @@ review: items: - id: VQ-01 name: Text Legibility - score: 8 + score: 7 max: 8 passed: true - comment: All font sizes explicitly set in Style object (title_font_size=72, - label_font_size=40, major_label_font_size=36, legend_font_size=44). Title - and legend text clearly readable in both themes. + comment: Font sizes explicitly set (title=72, legend=44, labels=40); all text + readable in both themes - id: VQ-02 name: No Overlap - score: 4 + score: 5 max: 6 passed: true - comment: Some node overlap in dense cluster areas (Engineering right cluster, - Sales top-left cluster) due to uniform node sizing and force-directed layout - density. + comment: Some node crowding in dense clusters inherent to 50-node network; + no text overlap - id: VQ-03 name: Element Visibility score: 5 max: 6 passed: true - comment: Nodes and edges clearly visible. dots_size=28 appropriate for canvas - size. Slight deduction for missing degree-based size scaling. + comment: Nodes clearly visible with degree-based sizing; edges rendered as + clean gray lines - id: VQ-04 name: Color Accessibility score: 2 max: 2 passed: true - comment: Okabe-Ito palette CVD-safe. Three communities distinguishable by - hue and luminance. opacity=0.9 appropriate. + comment: Okabe-Ito community colors (green/orange/blue); CVD-safe; muted edges + don't compete - id: VQ-05 name: Layout & Canvas score: 3 max: 4 passed: true - comment: Good canvas utilization (~70%). Legend at bottom. Force-directed - layout leaves some empty center-right space due to Engineering cluster being - pushed right. + comment: Network fills ~65-70% of canvas; slight wasted space at canvas edges - id: VQ-06 name: Axis Labels & Title score: 2 max: 2 passed: true - comment: 'Title format correct: ''network-force-directed · pygal · anyplot.ai''. - No axis labels — appropriate for force-directed network graph where XY coordinates - have no semantic meaning.' + comment: Title correctly formatted; no axis labels appropriate for network + graph type - id: VQ-07 name: Palette Compliance score: 1 max: 2 - passed: true - comment: 'Backgrounds correct (#FAF8F1 light, #1A1A17 dark). Community colors - follow Okabe-Ito in order. Chrome theme-correct in both renders. Partial - deduction: first chart series (Connections/edges) uses muted gray rather - than #009E73, technically violating first-series rule despite being semantically - correct for edge rendering.' + passed: false + comment: 'Community colors correctly use Okabe-Ito; but first series Connections + uses EDGE_COLOR not #009E73; both theme backgrounds correct' design_excellence: score: 13 max: 20 @@ -115,25 +107,24 @@ review: score: 5 max: 8 passed: true - comment: Professional network graph appearance. Thoughtful edge/node color - separation. Theme-adaptive styling. Above configured default but not publication-exceptional. + comment: 'Above default: degree-based sizing, muted edges vs bright community + nodes creates hierarchy' - id: DE-02 name: Visual Refinement score: 4 max: 6 passed: true - comment: Axes and grid guides appropriately hidden. Legend at bottom. Good - margins. Clean network layout. Functional refinement for network graph type. + comment: No grid or axis decorations; clean margins; legend neat; above library + defaults - id: DE-03 name: Data Storytelling score: 4 max: 6 passed: true - comment: Three community clusters with bridge edges tell a clear organizational - network story. Community separation through color creates immediate visual - insight. Hub nodes labeled in tooltips. + comment: Three communities immediately apparent; hub nodes visually stand + out; bridge edges tell inter-community connectivity story spec_compliance: - score: 15 + score: 14 max: 15 items: - id: SC-01 @@ -141,29 +132,27 @@ review: score: 5 max: 5 passed: true - comment: Force-directed graph with Fruchterman-Reingold physics simulation. - Correct node/edge structure. + comment: Force-directed graph with manual Fruchterman-Reingold implementation - id: SC-02 name: Required Features - score: 4 + score: 3 max: 4 passed: true - comment: Nodes with unique IDs, edges, force-directed layout, community structure - — all present. + comment: Node degree scaling, edge representation, community structure present; + edge thickness for weights not implemented (spec optional) - id: SC-03 name: Data Mapping score: 3 max: 3 passed: true - comment: Position mapped to force-directed coordinates. Communities mapped - to Okabe-Ito colors. Edges correctly drawn between node positions. + comment: Correct network topology; three-community structure clearly shown - id: SC-04 name: Title & Legend score: 3 max: 3 passed: true - comment: 'Title: ''network-force-directed · pygal · anyplot.ai'' correct. - Legend: Engineering, Marketing, Sales, Connections — all correctly labeled.' + comment: Title network-force-directed · pygal · anyplot.ai correct; legend + labels correct data_quality: score: 14 max: 15 @@ -173,23 +162,22 @@ review: score: 5 max: 6 passed: true - comment: 'Shows intra-community edges, inter-community bridge edges, community - clustering, hub nodes labeled in tooltips. Missing: visual degree-based - node sizing.' + comment: 'Shows communities, hub nodes, bridge edges, degree variation; minor: + no strongly isolated peripheral nodes' - id: DQ-02 name: Realistic Context score: 5 max: 5 passed: true - comment: Corporate social network (Engineering/Marketing/Sales departments) - — realistic, neutral, comprehensible scenario. + comment: Corporate social network (Engineering, Marketing, Sales) — realistic, + neutral scenario - id: DQ-03 name: Appropriate Scale score: 4 max: 4 passed: true - comment: 50 nodes, 3 communities (18/17/15 nodes), ~80+ edges. Appropriate - scale for force-directed network visualization. + comment: 50 nodes, 30% intra-community edge probability, 8 bridge edges; all + plausible code_quality: score: 10 max: 10 @@ -199,33 +187,33 @@ review: score: 3 max: 3 passed: true - comment: 'Clear procedural structure: imports → constants → data generation - → layout → styling → chart → save. No functions or classes.' + comment: 'Linear: imports -> tokens -> data -> layout -> plot -> save; no + functions or classes' - id: CQ-02 name: Reproducibility score: 2 max: 2 passed: true - comment: np.random.seed(42) set before data generation. + comment: np.random.seed(42) - id: CQ-03 name: Clean Imports score: 2 max: 2 passed: true - comment: All imports used. sys/Path workaround for name collision is explained. + comment: sys, pathlib.Path, os, numpy, pygal, pygal.style.Style — all used - id: CQ-04 name: Code Elegance score: 2 max: 2 passed: true - comment: Clean Pythonic code. FR algorithm well-structured. No over-engineering. + comment: Force-directed layout computation appropriate complexity; clean readable + code - id: CQ-05 name: Output & API score: 1 max: 1 passed: true - comment: Saves plot-{THEME}.svg, plot-{THEME}.png, plot-{THEME}.html. Current - pygal API used. + comment: Saves plot-{THEME}.png, .svg, .html library_mastery: score: 7 max: 10 @@ -235,26 +223,22 @@ review: score: 4 max: 5 passed: true - comment: Uses pygal.XY with Style object, series-based structure, interactive - tooltip labels. Correct stroke/show_dots per series. Good idiomatic usage. + comment: Uses pygal.XY, Style object for full theming, per-point node dict + for radius overrides, correct stroke/dots_size API - id: LM-02 name: Distinctive Features score: 3 max: 5 passed: true - comment: Interactive tooltips with node info (degree, hub status), HTML output - for interactive chart, None-break technique for edge line series — distinctive - pygal features utilized. - verdict: APPROVED + comment: Per-point SVG attribute overrides for degree-based radii; None-break + technique for edges; interactive HTML export + verdict: REJECTED impl_tags: dependencies: [] techniques: - html-export - - hover-tooltips patterns: - data-generation - iteration-over-groups dataprep: [] - styling: - - minimal-chrome - - alpha-blending + styling: []