Skip to content

Commit abb03bd

Browse files
update(dendrogram-basic): plotly — comprehensive quality review (#5202)
## Summary Updated **plotly** implementation for **dendrogram-basic**. **Changes:** Comprehensive review improving code quality, data choice, visual design, spec compliance, and library feature usage. ## Test Plan - [x] Preview images uploaded to GCS staging - [x] Implementation file passes ruff format/check - [x] Metadata YAML updated with current versions - [ ] Automated review triggered --- Generated with [Claude Code](https://claude.com/claude-code) `/update` command --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent f514b51 commit abb03bd

File tree

2 files changed

+199
-141
lines changed

2 files changed

+199
-141
lines changed
Lines changed: 54 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
""" pyplots.ai
22
dendrogram-basic: Basic Dendrogram
3-
Library: plotly 6.5.0 | Python 3.13.11
4-
Quality: 91/100 | Created: 2025-12-23
3+
Library: plotly 6.5.2 | Python 3.14.3
4+
Quality: 90/100 | Updated: 2026-04-05
55
"""
66

77
import numpy as np
88
import plotly.figure_factory as ff
9+
from scipy.cluster.hierarchy import linkage
910

1011

11-
# Data - Iris-like flower measurements for 15 samples
12+
# Data - Iris flower measurements for 15 samples across 3 species
1213
np.random.seed(42)
1314
labels = [
1415
"Setosa-1",
@@ -28,38 +29,68 @@
2829
"Virginica-5",
2930
]
3031

31-
# Create clustered data representing flower measurements (sepal length, sepal width, petal length, petal width)
32-
# Setosa: small petals, medium sepals
32+
# Sepal length, sepal width, petal length, petal width
3333
setosa = np.random.randn(5, 4) * 0.3 + np.array([5.0, 3.4, 1.5, 0.2])
34-
# Versicolor: medium measurements
3534
versicolor = np.random.randn(5, 4) * 0.4 + np.array([5.9, 2.8, 4.3, 1.3])
36-
# Virginica: large petals and sepals
3735
virginica = np.random.randn(5, 4) * 0.4 + np.array([6.6, 3.0, 5.5, 2.0])
38-
3936
data = np.vstack([setosa, versicolor, virginica])
4037

41-
# Create dendrogram
38+
# Colorscale: maps to scipy color keys (b, c, g, k, m, r, w, y) alphabetically
39+
# C0->b(idx 0), C1->g(idx 2), C2->r(idx 5), C3->c(idx 1), above-threshold->C0
40+
colorscale = [
41+
"#306998", # b -> Python Blue (above-threshold merges)
42+
"#E1974C", # c -> Warm amber
43+
"#52A675", # g -> Muted green
44+
"#333333", # k
45+
"#8B6BAE", # m
46+
"#D45B5B", # r -> Soft coral
47+
"#ffffff", # w
48+
"#C4A437", # y
49+
]
50+
4251
fig = ff.create_dendrogram(
43-
data,
44-
labels=labels,
45-
linkagefun=lambda x: __import__("scipy.cluster.hierarchy", fromlist=["linkage"]).linkage(x, method="ward"),
46-
color_threshold=3.0,
52+
data, labels=labels, colorscale=colorscale, linkagefun=lambda x: linkage(x, method="ward"), color_threshold=3.5
4753
)
4854

49-
# Update layout for large canvas
55+
# Add merge distance hover to each branch
56+
for trace in fig.data:
57+
trace.line.width = 3
58+
merge_height = max(y for y in trace.y if y > 0) if any(y > 0 for y in trace.y) else 0
59+
trace.hovertemplate = f"Merge distance: {merge_height:.2f}<extra></extra>"
60+
61+
# Layout
5062
fig.update_layout(
51-
title={"text": "dendrogram-basic · plotly · pyplots.ai", "font": {"size": 28}, "x": 0.5, "xanchor": "center"},
52-
xaxis={"title": {"text": "Iris Flower Samples", "font": {"size": 22}}, "tickfont": {"size": 16}, "tickangle": -45},
53-
yaxis={"title": {"text": "Distance (Ward)", "font": {"size": 22}}, "tickfont": {"size": 18}},
63+
title={
64+
"text": "dendrogram-basic · plotly · pyplots.ai",
65+
"font": {"size": 28, "color": "#2a2a2a", "family": "Arial, sans-serif"},
66+
"x": 0.5,
67+
"xanchor": "center",
68+
},
69+
xaxis={
70+
"title": {"text": "Iris Flower Samples", "font": {"size": 22}},
71+
"tickfont": {"size": 16},
72+
"tickangle": -35,
73+
"showline": True,
74+
"linecolor": "#cccccc",
75+
"zeroline": False,
76+
},
77+
yaxis={
78+
"title": {"text": "Distance (Ward linkage)", "font": {"size": 22}},
79+
"tickfont": {"size": 18},
80+
"showline": True,
81+
"linecolor": "#cccccc",
82+
"gridcolor": "rgba(0,0,0,0.06)",
83+
"gridwidth": 1,
84+
"zeroline": False,
85+
},
5486
template="plotly_white",
5587
width=1600,
5688
height=900,
57-
margin={"l": 80, "r": 40, "t": 100, "b": 150},
89+
margin={"l": 90, "r": 50, "t": 100, "b": 150},
90+
plot_bgcolor="#ffffff",
91+
hoverlabel={"bgcolor": "white", "font_size": 14, "bordercolor": "#cccccc"},
5892
)
5993

60-
# Update line widths for visibility
61-
fig.update_traces(line={"width": 3})
62-
63-
# Save outputs
94+
# Save
6495
fig.write_image("plot.png", width=1600, height=900, scale=3)
65-
fig.write_html("plot.html")
96+
fig.write_html("plot.html", include_plotlyjs="cdn")

0 commit comments

Comments
 (0)