Skip to content

Commit 60efd11

Browse files
update(heatmap-basic): altair — comprehensive quality review (#4256)
## Summary Updated **altair** implementation for **heatmap-basic**. **Changes:** Comprehensive quality review — fix weaknesses from prior reviews, preserve strengths, improve quality across all dimensions. ### Changes - Addressed review weaknesses from prior quality assessment - Improved data choice and visual design - Enhanced library-specific feature usage - Updated to current library and Python versions - Quality self-assessment: pending CI review ## 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 b6257ee commit 60efd11

2 files changed

Lines changed: 252 additions & 148 deletions

File tree

Lines changed: 108 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,141 @@
11
""" pyplots.ai
22
heatmap-basic: Basic Heatmap
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: 88/100 | Updated: 2026-02-16
55
"""
66

77
import altair as alt
88
import numpy as np
99
import pandas as pd
1010

1111

12-
# Data - create a matrix with patterns
12+
# Data - correlation matrix with realistic weather variables
1313
np.random.seed(42)
14-
rows = ["Row A", "Row B", "Row C", "Row D", "Row E", "Row F", "Row G", "Row H"]
15-
cols = ["Col 1", "Col 2", "Col 3", "Col 4", "Col 5", "Col 6", "Col 7", "Col 8"]
14+
variables = [
15+
"Temperature",
16+
"Humidity",
17+
"Wind Speed",
18+
"Pressure",
19+
"Visibility",
20+
"Cloud Cover",
21+
"Precipitation",
22+
"UV Index",
23+
]
1624

17-
# Generate values with some patterns (diagonal pattern + noise)
18-
values = []
19-
for i, row in enumerate(rows):
20-
for j, col in enumerate(cols):
21-
# Create pattern: higher values near diagonal, add noise
22-
base = 100 - abs(i - j) * 12
23-
noise = np.random.randn() * 10
24-
values.append({"x": col, "y": row, "value": base + noise})
25+
n_samples = 200
26+
raw = np.random.randn(n_samples, len(variables))
2527

26-
df = pd.DataFrame(values)
28+
# Inject realistic correlations with stronger relationships
29+
raw[:, 1] += raw[:, 0] * 0.6 # Humidity ~ Temperature
30+
raw[:, 5] += raw[:, 1] * 0.7 # Cloud Cover ~ Humidity
31+
raw[:, 6] += raw[:, 5] * 0.65 # Precipitation ~ Cloud Cover
32+
raw[:, 4] -= raw[:, 5] * 0.9 # Visibility inversely ~ Cloud Cover
33+
raw[:, 7] -= raw[:, 5] * 0.7 # UV Index inversely ~ Cloud Cover
34+
raw[:, 7] += raw[:, 0] * 0.5 # UV Index ~ Temperature
35+
raw[:, 3] -= raw[:, 0] * 0.4 # Pressure inversely ~ Temperature
36+
raw[:, 2] += raw[:, 3] * 0.3 # Wind Speed ~ Pressure
2737

28-
# Plot - heatmap base
38+
corr = np.corrcoef(raw.T)
39+
40+
# Build long-form dataframe using list comprehension
41+
df = pd.DataFrame(
42+
[
43+
{"Row": row_var, "Column": col_var, "value": round(corr[i, j], 2)}
44+
for i, row_var in enumerate(variables)
45+
for j, col_var in enumerate(variables)
46+
]
47+
)
48+
49+
# Axis ordering
50+
axis_order = list(variables)
51+
52+
# Plot - heatmap with colorblind-safe diverging color centered at 0
2953
heatmap = (
3054
alt.Chart(df)
31-
.mark_rect()
55+
.mark_rect(stroke="#ffffff", strokeWidth=1.5, cornerRadius=2)
3256
.encode(
33-
x=alt.X("x:N", title="Column", axis=alt.Axis(labelFontSize=16, titleFontSize=20)),
34-
y=alt.Y("y:N", title="Row", axis=alt.Axis(labelFontSize=16, titleFontSize=20)),
57+
x=alt.X(
58+
"Column:N",
59+
title="Weather Variable",
60+
sort=axis_order,
61+
axis=alt.Axis(
62+
labelFontSize=15, titleFontSize=18, labelAngle=-45, orient="top", labelPadding=8, titlePadding=10
63+
),
64+
),
65+
y=alt.Y(
66+
"Row:N",
67+
title="Weather Variable",
68+
sort=axis_order,
69+
axis=alt.Axis(labelFontSize=15, titleFontSize=18, labelPadding=8, titlePadding=10),
70+
),
3571
color=alt.Color(
3672
"value:Q",
37-
scale=alt.Scale(scheme="blueorange", domainMid=50),
38-
legend=alt.Legend(title="Value", titleFontSize=18, labelFontSize=16),
73+
scale=alt.Scale(scheme="blueorange", domain=[-1, 1], domainMid=0),
74+
legend=alt.Legend(
75+
title="Correlation",
76+
titleFontSize=16,
77+
labelFontSize=14,
78+
gradientLength=300,
79+
gradientThickness=16,
80+
titlePadding=6,
81+
offset=8,
82+
direction="vertical",
83+
),
3984
),
40-
tooltip=["x:N", "y:N", "value:Q"],
85+
tooltip=[
86+
alt.Tooltip("Column:N", title="Column"),
87+
alt.Tooltip("Row:N", title="Row"),
88+
alt.Tooltip("value:Q", title="Correlation", format=".2f"),
89+
],
4190
)
4291
)
4392

44-
# Add text annotations
93+
# Highlight cells with strong correlations using thicker borders
94+
highlight = (
95+
alt.Chart(df)
96+
.transform_filter((alt.datum.value >= 0.7) | (alt.datum.value <= -0.7))
97+
.mark_rect(stroke="#2a2a2a", strokeWidth=2.5, filled=False, cornerRadius=2)
98+
.encode(x=alt.X("Column:N", sort=axis_order), y=alt.Y("Row:N", sort=axis_order))
99+
)
100+
101+
# Text annotations with adaptive color
45102
text = (
46103
alt.Chart(df)
47-
.mark_text(fontSize=18)
104+
.mark_text(fontSize=15, fontWeight="bold")
48105
.encode(
49-
x=alt.X("x:N"),
50-
y=alt.Y("y:N"),
51-
text=alt.Text("value:Q", format=".0f"),
52-
color=alt.condition(alt.datum.value > 70, alt.value("white"), alt.value("black")),
106+
x=alt.X("Column:N", sort=axis_order),
107+
y=alt.Y("Row:N", sort=axis_order),
108+
text=alt.Text("value:Q", format=".2f"),
109+
color=alt.when((alt.datum.value > 0.55) | (alt.datum.value < -0.55))
110+
.then(alt.value("#ffffff"))
111+
.otherwise(alt.value("#333333")),
53112
)
54113
)
55114

56-
# Combine heatmap and text, then apply configuration
115+
# Combine layers and configure
57116
chart = (
58-
(heatmap + text)
59-
.properties(width=1400, height=800, title=alt.Title("heatmap-basic · altair · pyplots.ai", fontSize=28))
60-
.configure_axis(labelFontSize=16, titleFontSize=20, grid=False)
117+
(heatmap + highlight + text)
118+
.properties(
119+
width=740,
120+
height=766,
121+
title=alt.Title(
122+
"heatmap-basic · altair · pyplots.ai",
123+
subtitle=[
124+
"Pairwise Pearson correlation coefficients for 8 weather metrics.",
125+
"Bold borders highlight strong relationships (|r| ≥ 0.7).",
126+
],
127+
fontSize=26,
128+
subtitleFontSize=16,
129+
subtitleColor="#666666",
130+
anchor="start",
131+
offset=16,
132+
),
133+
padding={"left": 20, "right": 20, "top": 20, "bottom": 20},
134+
)
135+
.configure_axis(grid=False)
61136
.configure_view(strokeWidth=0)
62137
)
63138

64-
# Save
65-
chart.save("plot.png", scale_factor=3.0)
139+
# Save — target: 3600×3600 square format
140+
chart.save("plot.png", scale_factor=3.6)
66141
chart.save("plot.html")

0 commit comments

Comments
 (0)