Skip to content

Commit 6af62a3

Browse files
update(arc-basic): altair — comprehensive quality review
Comprehensive review and update of altair implementation for arc-basic.
1 parent b1e8c8c commit 6af62a3

2 files changed

Lines changed: 60 additions & 31 deletions

File tree

Lines changed: 56 additions & 27 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: altair 6.0.0 | Python 3.13.11
4-
Quality: 91/100 | Created: 2025-12-23
3+
Library: altair 6.0.0 | Python 3.14.3
4+
Quality: /100 | Updated: 2026-02-23
55
"""
66

77
import altair as alt
@@ -15,9 +15,8 @@
1515
nodes = ["Alice", "Bob", "Carol", "David", "Eve", "Frank", "Grace", "Henry", "Iris", "Jack"]
1616
n_nodes = len(nodes)
1717

18-
# Edges: pairs of connected nodes with weights
1918
edges = [
20-
(0, 1, 3), # Alice-Bob (strong connection)
19+
(0, 1, 3), # Alice-Bob (strong)
2120
(0, 3, 2), # Alice-David
2221
(1, 2, 2), # Bob-Carol
2322
(2, 4, 1), # Carol-Eve
@@ -36,68 +35,95 @@
3635

3736
# Node positions along x-axis
3837
x_positions = np.linspace(0, 100, n_nodes)
39-
y_baseline = 10
38+
y_baseline = 0
4039

41-
# Create node dataframe
42-
nodes_df = pd.DataFrame({"x": x_positions, "y": [y_baseline] * n_nodes, "name": nodes})
40+
# Node dataframe with connection count for sizing
41+
connection_count = [0] * n_nodes
42+
for s, e, w in edges:
43+
connection_count[s] += w
44+
connection_count[e] += w
4345

44-
# Create arc paths - each arc as a series of points following a semicircle
46+
nodes_df = pd.DataFrame({"x": x_positions, "y": [y_baseline] * n_nodes, "name": nodes, "connections": connection_count})
47+
48+
# Build arc paths as semicircular curves
4549
arc_data = []
4650
points_per_arc = 50
51+
max_span = max(abs(e - s) for s, e, _ in edges)
4752

4853
for edge_id, (start, end, weight) in enumerate(edges):
4954
x_start = x_positions[start]
5055
x_end = x_positions[end]
56+
span = abs(end - start)
57+
height = 7 * span
5158

52-
# Arc height proportional to distance between nodes
53-
distance = abs(end - start)
54-
height = 8 * distance
55-
56-
# Generate points along a semicircle arc
5759
angles = np.linspace(0, np.pi, points_per_arc)
58-
5960
x_center = (x_start + x_end) / 2
6061
radius_x = abs(x_end - x_start) / 2
6162
radius_y = height / 2
6263

64+
pair = f"{nodes[start]}{nodes[end]}"
6365
for i, angle in enumerate(angles):
6466
arc_data.append(
6567
{
6668
"edge_id": edge_id,
6769
"x": x_center - radius_x * np.cos(angle),
6870
"y": y_baseline + radius_y * np.sin(angle),
6971
"weight": weight,
72+
"pair": pair,
7073
"order": i,
7174
}
7275
)
7376

7477
arcs_df = pd.DataFrame(arc_data)
7578

76-
# Create arc chart with lines
79+
# Y-domain: tight around data for better canvas use
80+
max_arc_height = 7 * max_span / 2
81+
y_domain = [-4, max_arc_height + 4]
82+
83+
# Arcs: weight drives both thickness and opacity for visual hierarchy
7784
arcs = (
7885
alt.Chart(arcs_df)
79-
.mark_line(strokeWidth=2, opacity=0.6)
86+
.mark_line()
8087
.encode(
8188
x=alt.X("x:Q", axis=None),
82-
y=alt.Y("y:Q", axis=None),
89+
y=alt.Y("y:Q", axis=None, scale=alt.Scale(domain=y_domain)),
8390
detail="edge_id:N",
84-
strokeWidth=alt.StrokeWidth("weight:Q", scale=alt.Scale(domain=[1, 3], range=[2, 6]), legend=None),
91+
strokeWidth=alt.StrokeWidth(
92+
"weight:Q",
93+
scale=alt.Scale(domain=[1, 3], range=[1.5, 5]),
94+
legend=alt.Legend(
95+
title="Interaction Strength",
96+
titleFontSize=16,
97+
labelFontSize=14,
98+
orient="top-right",
99+
offset=10,
100+
values=[1, 2, 3],
101+
symbolStrokeWidth=3,
102+
labelExpr="datum.value == 1 ? 'Weak' : datum.value == 2 ? 'Moderate' : 'Strong'",
103+
),
104+
),
105+
strokeOpacity=alt.StrokeOpacity("weight:Q", scale=alt.Scale(domain=[1, 3], range=[0.35, 0.7]), legend=None),
85106
color=alt.value("#306998"),
107+
tooltip=[alt.Tooltip("pair:N", title="Connection"), alt.Tooltip("weight:Q", title="Strength")],
86108
)
87-
.properties(width=1600, height=900)
88109
)
89110

90-
# Create node points
111+
# Nodes: size proportional to total connection weight
91112
node_points = (
92113
alt.Chart(nodes_df)
93-
.mark_circle(size=600, color="#FFD43B", stroke="#306998", strokeWidth=3)
94-
.encode(x=alt.X("x:Q", axis=None), y=alt.Y("y:Q", axis=None))
114+
.mark_circle(color="#FFD43B", stroke="#306998", strokeWidth=2.5)
115+
.encode(
116+
x=alt.X("x:Q", axis=None),
117+
y=alt.Y("y:Q", axis=None, scale=alt.Scale(domain=y_domain)),
118+
size=alt.Size("connections:Q", scale=alt.Scale(domain=[2, 11], range=[300, 800]), legend=None),
119+
tooltip=[alt.Tooltip("name:N", title="Character"), alt.Tooltip("connections:Q", title="Total Weight")],
120+
)
95121
)
96122

97-
# Create node labels
123+
# Node labels below baseline
98124
node_labels = (
99125
alt.Chart(nodes_df)
100-
.mark_text(dy=30, fontSize=18, fontWeight="bold", color="#306998")
126+
.mark_text(dy=26, fontSize=18, fontWeight="bold", color="#306998")
101127
.encode(x=alt.X("x:Q"), y=alt.Y("y:Q"), text="name:N")
102128
)
103129

@@ -107,11 +133,14 @@
107133
.properties(
108134
width=1600,
109135
height=900,
110-
title=alt.Title("Character Interactions · arc-basic · altair · pyplots.ai", fontSize=28, anchor="middle"),
136+
title=alt.Title(
137+
"Character Interactions · arc-basic · altair · pyplots.ai", fontSize=28, anchor="middle", offset=15
138+
),
111139
)
112140
.configure_view(strokeWidth=0)
141+
.configure_legend(strokeColor="transparent", padding=12)
113142
)
114143

115-
# Save outputs
144+
# Save
116145
chart.save("plot.png", scale_factor=3.0)
117146
chart.save("plot.html")

plots/arc-basic/metadata/altair.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
library: altair
22
specification_id: arc-basic
33
created: '2025-12-23T08:49:37Z'
4-
updated: '2025-12-23T09:04:22Z'
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: 20455963635
77
issue: 0
8-
python_version: 3.13.11
8+
python_version: '3.14.3'
99
library_version: 6.0.0
1010
preview_url: https://storage.googleapis.com/pyplots-images/plots/arc-basic/altair/plot.png
1111
preview_thumb: https://storage.googleapis.com/pyplots-images/plots/arc-basic/altair/plot_thumb.png
1212
preview_html: https://storage.googleapis.com/pyplots-images/plots/arc-basic/altair/plot.html
13-
quality_score: 91
13+
quality_score: null
1414
impl_tags:
1515
dependencies: []
1616
techniques:

0 commit comments

Comments
 (0)