Skip to content

Commit 62e7a15

Browse files
update(arc-basic): letsplot — comprehensive quality review
Comprehensive review and update of letsplot implementation for arc-basic.
1 parent b1e8c8c commit 62e7a15

2 files changed

Lines changed: 83 additions & 32 deletions

File tree

Lines changed: 79 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
""" pyplots.ai
1+
"""pyplots.ai
22
arc-basic: Basic Arc Diagram
3-
Library: letsplot 4.8.2 | Python 3.13.11
4-
Quality: 92/100 | Created: 2025-12-23
3+
Library: letsplot 4.8.2 | Python 3.14.3
4+
Quality: /100 | Updated: 2026-02-23
55
"""
66

77
import numpy as np
@@ -10,13 +10,18 @@
1010
LetsPlot,
1111
aes,
1212
element_blank,
13+
element_rect,
1314
element_text,
1415
geom_path,
1516
geom_point,
17+
geom_segment,
1618
geom_text,
1719
ggplot,
1820
ggsize,
1921
labs,
22+
layer_tooltips,
23+
scale_alpha_identity,
24+
scale_color_identity,
2025
scale_size_identity,
2126
theme,
2227
xlim,
@@ -28,14 +33,12 @@
2833
LetsPlot.setup_html()
2934

3035
# Data: Character interactions in a story chapter
31-
np.random.seed(42)
32-
3336
nodes = ["Alice", "Bob", "Carol", "David", "Eve", "Frank", "Grace", "Henry", "Iris", "Jack"]
3437
n_nodes = len(nodes)
3538

3639
# Edges: pairs of connected nodes with weights (source, target, weight)
3740
edges = [
38-
(0, 1, 3), # Alice-Bob (strong connection)
41+
(0, 1, 3), # Alice-Bob (strong)
3942
(0, 3, 2), # Alice-David
4043
(1, 2, 2), # Bob-Carol
4144
(2, 4, 1), # Carol-Eve
@@ -54,7 +57,18 @@
5457

5558
# Node positions along x-axis
5659
x_positions = np.linspace(0, 1, n_nodes)
57-
y_baseline = 0.1
60+
y_baseline = 0.08
61+
62+
# Count connections per node for visual hierarchy
63+
connections = [0] * n_nodes
64+
for s, t, w in edges:
65+
connections[s] += w
66+
connections[t] += w
67+
68+
# Arc color intensity by weight
69+
weight_colors = {1: "#93B8CC", 2: "#306998", 3: "#1A3A5C"}
70+
weight_alphas = {1: 0.5, 2: 0.65, 3: 0.8}
71+
weight_labels = {1: "Weak", 2: "Moderate", 3: "Strong"}
5872

5973
# Create arc data for geom_path
6074
arc_data = []
@@ -66,57 +80,94 @@
6680
distance = abs(end - start)
6781
height = 0.08 * distance
6882

69-
# Generate points along the arc (semi-circle)
83+
# Generate points along the arc
7084
n_points = 50
7185
t = np.linspace(0, np.pi, n_points)
7286
arc_x = x_start + (x_end - x_start) * (1 - np.cos(t)) / 2
7387
arc_y = y_baseline + height * np.sin(t)
7488

75-
# Line width based on weight
76-
line_size = 1.5 + weight * 1.0
89+
line_size = 1.0 + weight * 1.2
90+
color = weight_colors[weight]
91+
alpha = weight_alphas[weight]
92+
tooltip_text = f"{nodes[start]} \u2194 {nodes[end]}"
93+
strength = weight_labels[weight]
7794

7895
for i in range(n_points):
79-
arc_data.append({"x": arc_x[i], "y": arc_y[i], "edge_id": edge_id, "weight": weight, "size": line_size})
96+
arc_data.append(
97+
{
98+
"x": arc_x[i],
99+
"y": arc_y[i],
100+
"edge_id": edge_id,
101+
"size": line_size,
102+
"color": color,
103+
"alpha": alpha,
104+
"connection": tooltip_text,
105+
"strength": strength,
106+
}
107+
)
80108

81109
arc_df = pd.DataFrame(arc_data)
82110

83-
# Node data
84-
node_df = pd.DataFrame({"x": x_positions, "y": [y_baseline] * n_nodes, "name": nodes})
111+
# Node data with size based on total connection weight
112+
max_conn = max(connections)
113+
node_sizes = [6 + 10 * (c / max_conn) for c in connections]
114+
node_df = pd.DataFrame(
115+
{"x": x_positions, "y": [y_baseline] * n_nodes, "name": nodes, "node_size": node_sizes, "connections": connections}
116+
)
117+
118+
# Baseline segment data
119+
baseline_df = pd.DataFrame({"x": [x_positions[0]], "xend": [x_positions[-1]], "y": [y_baseline], "yend": [y_baseline]})
85120

86121
# Label data (positioned below nodes)
87-
label_df = pd.DataFrame({"x": x_positions, "y": [y_baseline - 0.05] * n_nodes, "name": nodes})
122+
label_df = pd.DataFrame({"x": x_positions, "y": [y_baseline - 0.045] * n_nodes, "name": nodes})
88123

89-
# Create plot
124+
# Plot
90125
plot = (
91126
ggplot()
92-
# Draw arcs with semi-transparency for overlapping connections
93-
+ geom_path(data=arc_df, mapping=aes(x="x", y="y", group="edge_id", size="size"), color="#306998", alpha=0.6)
127+
# Subtle baseline
128+
+ geom_segment(data=baseline_df, mapping=aes(x="x", y="y", xend="xend", yend="yend"), color="#D0D8E0", size=0.8)
129+
# Arcs with weight-based color, transparency, and tooltips
130+
+ geom_path(
131+
data=arc_df,
132+
mapping=aes(x="x", y="y", group="edge_id", size="size", color="color", alpha="alpha"),
133+
tooltips=layer_tooltips().line("@connection").line("Strength: @strength"),
134+
)
135+
+ scale_size_identity()
136+
+ scale_color_identity()
137+
+ scale_alpha_identity()
138+
# Nodes sized by connection weight with tooltips
139+
+ geom_point(
140+
data=node_df,
141+
mapping=aes(x="x", y="y", size="node_size"),
142+
color="#1A3A5C",
143+
fill="#FFD43B",
144+
stroke=1.5,
145+
shape=21,
146+
tooltips=layer_tooltips().line("@name").line("Connections: @connections"),
147+
)
94148
+ scale_size_identity()
95-
# Draw nodes
96-
+ geom_point(data=node_df, mapping=aes(x="x", y="y"), size=10, color="#FFD43B", fill="#FFD43B", stroke=2, shape=21)
97-
# Add node labels
149+
# Node labels
98150
+ geom_text(
99-
data=label_df, mapping=aes(x="x", y="y", label="name"), size=14, color="#306998", fontface="bold", vjust=1
151+
data=label_df, mapping=aes(x="x", y="y", label="name"), size=16, color="#1A3A5C", fontface="bold", vjust=1
100152
)
101153
# Styling
102-
+ xlim(-0.05, 1.05)
154+
+ xlim(-0.06, 1.06)
103155
+ ylim(-0.15, 0.85)
104-
+ labs(title="Character Interactions · arc-basic · letsplot · pyplots.ai")
156+
+ labs(title="Character Interactions \u00b7 arc-basic \u00b7 letsplot \u00b7 pyplots.ai")
105157
+ theme(
106158
axis_title=element_blank(),
107159
axis_text=element_blank(),
108160
axis_ticks=element_blank(),
109161
axis_line=element_blank(),
110162
panel_grid=element_blank(),
111-
panel_background=element_blank(),
112-
plot_title=element_text(size=24, face="bold"),
163+
panel_background=element_rect(fill="white", color="white"),
164+
plot_background=element_rect(fill="white", color="white"),
165+
plot_title=element_text(size=24, face="bold", color="#1A3A5C"),
113166
legend_position="none",
114167
)
115168
+ ggsize(1600, 900)
116169
)
117170

118-
# Save as PNG (scale 3x to get 4800 x 2700 px)
171+
# Save
119172
ggsave(plot, "plot.png", path=".", scale=3)
120-
121-
# Save as HTML for interactive viewing
122173
ggsave(plot, "plot.html", path=".")

plots/arc-basic/metadata/letsplot.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
library: letsplot
22
specification_id: arc-basic
33
created: '2025-12-23T08:49:14Z'
4-
updated: '2025-12-23T09:04:29Z'
5-
generated_by: claude-opus-4-5-20251101
4+
updated: '2026-02-23T12:00:00+00:00'
5+
generated_by: claude-opus-4-6
66
workflow_run: 20455965726
77
issue: 0
8-
python_version: 3.13.11
8+
python_version: '3.14.3'
99
library_version: 4.8.2
1010
preview_url: https://storage.googleapis.com/pyplots-images/plots/arc-basic/letsplot/plot.png
1111
preview_thumb: https://storage.googleapis.com/pyplots-images/plots/arc-basic/letsplot/plot_thumb.png
1212
preview_html: https://storage.googleapis.com/pyplots-images/plots/arc-basic/letsplot/plot.html
13-
quality_score: 92
13+
quality_score: null
1414
impl_tags:
1515
dependencies: []
1616
techniques:

0 commit comments

Comments
 (0)