Skip to content

Commit 7674e5c

Browse files
update(dendrogram-basic): matplotlib — comprehensive quality review (#5200)
## Summary Updated **matplotlib** implementation for **dendrogram-basic**. **Changes:** Comprehensive review improving code quality, data choice, visual design, spec compliance, and library feature usage. ### Changes - Improved color-coded species clustering with descriptive labels - Enhanced axis labels and title formatting - Updated Python version to 3.14.3 ## 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> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
1 parent abb03bd commit 7674e5c

File tree

4 files changed

+197
-154
lines changed

4 files changed

+197
-154
lines changed
Lines changed: 57 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,19 @@
11
""" pyplots.ai
22
dendrogram-basic: Basic Dendrogram
3-
Library: matplotlib 3.10.8 | Python 3.13.11
4-
Quality: 91/100 | Created: 2025-12-23
3+
Library: matplotlib 3.10.8 | Python 3.14.3
4+
Quality: 92/100 | Updated: 2026-04-05
55
"""
66

77
import matplotlib.pyplot as plt
88
import numpy as np
9-
from scipy.cluster.hierarchy import dendrogram, linkage
9+
from matplotlib.collections import LineCollection
10+
from scipy.cluster.hierarchy import dendrogram, linkage, set_link_color_palette
1011

1112

1213
# Data - Iris flower measurements (4 features for 15 samples)
1314
np.random.seed(42)
1415

15-
# Simulate iris-like measurements: sepal length, sepal width, petal length, petal width
16-
# Three species with distinct characteristics
1716
samples_per_species = 5
18-
1917
labels = []
2018
data = []
2119

@@ -24,10 +22,10 @@
2422
labels.append(f"Setosa-{i + 1}")
2523
data.append(
2624
[
27-
5.0 + np.random.randn() * 0.3, # sepal length
28-
3.4 + np.random.randn() * 0.3, # sepal width
29-
1.5 + np.random.randn() * 0.2, # petal length
30-
0.3 + np.random.randn() * 0.1, # petal width
25+
5.0 + np.random.randn() * 0.3,
26+
3.4 + np.random.randn() * 0.3,
27+
1.5 + np.random.randn() * 0.2,
28+
0.3 + np.random.randn() * 0.1,
3129
]
3230
)
3331

@@ -36,10 +34,10 @@
3634
labels.append(f"Versicolor-{i + 1}")
3735
data.append(
3836
[
39-
5.9 + np.random.randn() * 0.4, # sepal length
40-
2.8 + np.random.randn() * 0.3, # sepal width
41-
4.3 + np.random.randn() * 0.4, # petal length
42-
1.3 + np.random.randn() * 0.2, # petal width
37+
5.9 + np.random.randn() * 0.4,
38+
2.8 + np.random.randn() * 0.3,
39+
4.3 + np.random.randn() * 0.4,
40+
1.3 + np.random.randn() * 0.2,
4341
]
4442
)
4543

@@ -48,10 +46,10 @@
4846
labels.append(f"Virginica-{i + 1}")
4947
data.append(
5048
[
51-
6.6 + np.random.randn() * 0.5, # sepal length
52-
3.0 + np.random.randn() * 0.3, # sepal width
53-
5.5 + np.random.randn() * 0.5, # petal length
54-
2.0 + np.random.randn() * 0.3, # petal width
49+
6.6 + np.random.randn() * 0.5,
50+
3.0 + np.random.randn() * 0.3,
51+
5.5 + np.random.randn() * 0.5,
52+
2.0 + np.random.randn() * 0.3,
5553
]
5654
)
5755

@@ -61,33 +59,57 @@
6159
linkage_matrix = linkage(data, method="ward")
6260

6361
# Plot
64-
fig, ax = plt.subplots(figsize=(16, 9))
62+
fig, ax = plt.subplots(figsize=(16, 9), facecolor="white")
63+
ax.set_facecolor("#FAFAFA")
64+
65+
# Custom cluster colors via set_link_color_palette (matplotlib/scipy integration)
66+
cluster_colors = ["#306998", "#D4722A", "#3A8A5C"]
67+
set_link_color_palette(cluster_colors)
68+
69+
# Set threshold between the 2nd and 3rd highest merge distances to reveal 3 clusters
70+
sorted_distances = sorted(linkage_matrix[:, 2])
71+
color_threshold = (sorted_distances[-2] + sorted_distances[-3]) / 2
6572

66-
# Create dendrogram with custom colors
67-
dendrogram(
73+
dendro = dendrogram(
6874
linkage_matrix,
6975
labels=labels,
7076
ax=ax,
71-
leaf_rotation=45,
72-
leaf_font_size=14,
73-
above_threshold_color="#306998", # Python Blue for main branches
74-
color_threshold=0.7 * max(linkage_matrix[:, 2]), # Color threshold for clusters
77+
leaf_rotation=40,
78+
leaf_font_size=16,
79+
above_threshold_color="#AAAAAA",
80+
color_threshold=color_threshold,
7581
)
7682

83+
# Post-render enhancement: adjust line widths via LineCollection traversal
84+
for child in ax.get_children():
85+
if isinstance(child, LineCollection):
86+
child.set_linewidths(3.0)
87+
child.set_capstyle("round")
88+
child.set_joinstyle("round")
89+
7790
# Style
78-
ax.set_xlabel("Sample", fontsize=20)
79-
ax.set_ylabel("Distance (Ward)", fontsize=20)
80-
ax.set_title("dendrogram-basic · matplotlib · pyplots.ai", fontsize=24)
81-
ax.tick_params(axis="both", labelsize=16)
82-
ax.tick_params(axis="x", labelsize=14, rotation=45)
91+
ax.set_xlabel("Iris Sample", fontsize=20, labelpad=10)
92+
ax.set_ylabel("Ward Linkage Distance", fontsize=20, labelpad=10)
93+
ax.set_title(
94+
"Iris Species Clustering · dendrogram-basic · matplotlib · pyplots.ai",
95+
fontsize=24,
96+
fontweight="medium",
97+
pad=20,
98+
color="#333333",
99+
)
100+
ax.tick_params(axis="both", labelsize=16, colors="#555555")
101+
ax.tick_params(axis="x", labelsize=16, rotation=40)
83102

84-
# Adjust spines for cleaner look
85103
ax.spines["top"].set_visible(False)
86104
ax.spines["right"].set_visible(False)
105+
ax.spines["left"].set_linewidth(0.6)
106+
ax.spines["left"].set_color("#CCCCCC")
107+
ax.spines["bottom"].set_linewidth(0.6)
108+
ax.spines["bottom"].set_color("#CCCCCC")
87109

88-
# Add subtle grid on y-axis only
89-
ax.yaxis.grid(True, alpha=0.3, linestyle="--")
110+
# Subtle grid on y-axis only
111+
ax.yaxis.grid(True, alpha=0.15, linewidth=0.6, color="#888888")
90112
ax.set_axisbelow(True)
91113

92-
plt.tight_layout()
93-
plt.savefig("plot.png", dpi=300, bbox_inches="tight")
114+
plt.tight_layout(pad=1.5)
115+
plt.savefig("plot.png", dpi=300, bbox_inches="tight", facecolor="white")

0 commit comments

Comments
 (0)