|
1 | 1 | """ pyplots.ai |
2 | 2 | heatmap-basic: Basic Heatmap |
3 | | -Library: plotly 6.5.0 | Python 3.13.11 |
4 | | -Quality: 92/100 | Created: 2025-12-23 |
| 3 | +Library: plotly 6.5.2 | Python 3.14.3 |
| 4 | +Quality: 92/100 | Updated: 2026-02-15 |
5 | 5 | """ |
6 | 6 |
|
7 | 7 | import numpy as np |
|
11 | 11 | # Data |
12 | 12 | np.random.seed(42) |
13 | 13 |
|
14 | | -# Create sample data: monthly sales across different product categories |
15 | 14 | months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] |
16 | | -categories = ["Electronics", "Clothing", "Food", "Books", "Sports", "Home", "Beauty", "Toys"] |
| 15 | +categories = ["Electronics", "Clothing", "Food & Beverage", "Books", "Sports", "Home & Garden", "Beauty", "Toys"] |
17 | 16 |
|
18 | | -# Generate realistic-looking data with some patterns |
19 | | -values = np.random.randn(len(categories), len(months)) * 20 + 50 |
20 | | -# Add seasonal patterns |
21 | | -for month_idx in [5, 6, 7]: # Summer boost |
22 | | - values[:, month_idx] += 15 |
23 | | -for month_idx in [10, 11]: # Holiday boost |
24 | | - values[:, month_idx] += 25 |
| 17 | +# Monthly sales growth (%) relative to annual average — diverging around zero |
| 18 | +base = np.random.randn(len(categories), len(months)) * 8 |
| 19 | +# Seasonal patterns: summer lift for outdoor/leisure, holiday lift for gifts |
| 20 | +for i, cat in enumerate(categories): |
| 21 | + if cat in ("Sports", "Toys", "Home & Garden"): |
| 22 | + base[i, 5:8] += 12 # Summer |
| 23 | + if cat in ("Electronics", "Toys", "Books", "Beauty"): |
| 24 | + base[i, 10:12] += 18 # Holiday season |
| 25 | + if cat == "Food & Beverage": |
| 26 | + base[i, 10:12] += 8 # Modest holiday lift |
| 27 | + if cat == "Clothing": |
| 28 | + base[i, 3:5] += 10 # Spring fashion |
| 29 | + base[i, 8:10] += 10 # Back-to-school |
| 30 | +values = np.round(base, 1) |
| 31 | + |
| 32 | +# Font family for publication-quality typography |
| 33 | +font_family = "Palatino, Georgia, serif" |
25 | 34 |
|
26 | 35 | # Plot |
27 | 36 | fig = go.Figure( |
28 | 37 | data=go.Heatmap( |
29 | 38 | z=values, |
30 | 39 | x=months, |
31 | 40 | y=categories, |
32 | | - colorscale="RdBu_r", # Diverging colormap |
| 41 | + colorscale="RdBu_r", |
| 42 | + zmid=0, |
33 | 43 | colorbar={ |
34 | | - "title": {"text": "Sales ($K)", "font": {"size": 20}}, |
35 | | - "tickfont": {"size": 16}, |
36 | | - "thickness": 30, |
37 | | - "len": 0.8, |
| 44 | + "title": {"text": "Sales Growth (%)", "font": {"size": 20, "family": font_family}}, |
| 45 | + "tickfont": {"size": 16, "family": font_family}, |
| 46 | + "ticksuffix": "%", |
| 47 | + "thickness": 20, |
| 48 | + "len": 0.75, |
| 49 | + "x": 1.005, |
| 50 | + "xpad": 4, |
| 51 | + "outlinewidth": 0, |
38 | 52 | }, |
39 | | - text=np.round(values, 0).astype(int), |
40 | | - texttemplate="%{text}", |
41 | | - textfont={"size": 14}, |
42 | | - hoverongaps=False, |
| 53 | + text=values, |
| 54 | + texttemplate="%{text:+.1f}", |
| 55 | + textfont={"size": 15, "family": font_family}, |
| 56 | + hovertemplate="<b>%{y}</b> · %{x}<br>Growth: %{z:+.1f}%<extra></extra>", |
| 57 | + xgap=2, |
| 58 | + ygap=2, |
43 | 59 | ) |
44 | 60 | ) |
45 | 61 |
|
46 | | -# Layout |
| 62 | +# Layout — tighter margins maximise heatmap area; serif font elevates polish |
47 | 63 | fig.update_layout( |
48 | | - title={"text": "heatmap-basic · plotly · pyplots.ai", "font": {"size": 32}, "x": 0.5, "xanchor": "center"}, |
49 | | - xaxis={"title": {"text": "Month", "font": {"size": 24}}, "tickfont": {"size": 18}, "side": "bottom"}, |
| 64 | + title={ |
| 65 | + "text": ( |
| 66 | + "Monthly Sales Growth · heatmap-basic · plotly · pyplots.ai" |
| 67 | + "<br><sup style='color:#555; font-size:17px; letter-spacing:0.3px'>" |
| 68 | + "Retail categories show clear seasonal surges — " |
| 69 | + "summer outdoor/leisure peaks and Q4 holiday gift spikes" |
| 70 | + "</sup>" |
| 71 | + ), |
| 72 | + "font": {"size": 28, "family": font_family, "color": "#1a1a1a"}, |
| 73 | + "x": 0.5, |
| 74 | + "xanchor": "center", |
| 75 | + "y": 0.97, |
| 76 | + "yanchor": "top", |
| 77 | + }, |
| 78 | + xaxis={ |
| 79 | + "title": {"text": "Month", "font": {"size": 22, "family": font_family, "color": "#333"}}, |
| 80 | + "tickfont": {"size": 18, "family": font_family, "color": "#444"}, |
| 81 | + "side": "bottom", |
| 82 | + }, |
50 | 83 | yaxis={ |
51 | | - "title": {"text": "Category", "font": {"size": 24}}, |
52 | | - "tickfont": {"size": 18}, |
53 | | - "autorange": "reversed", # Categories from top to bottom |
| 84 | + "title": {"text": "Product Category", "font": {"size": 22, "family": font_family, "color": "#333"}}, |
| 85 | + "tickfont": {"size": 18, "family": font_family, "color": "#444"}, |
| 86 | + "autorange": "reversed", |
54 | 87 | }, |
55 | 88 | template="plotly_white", |
56 | | - margin={"l": 120, "r": 100, "t": 100, "b": 80}, |
| 89 | + margin={"l": 140, "r": 60, "t": 120, "b": 65}, |
| 90 | + width=1600, |
| 91 | + height=900, |
| 92 | + paper_bgcolor="#fafafa", |
| 93 | + plot_bgcolor="#fafafa", |
57 | 94 | ) |
58 | 95 |
|
59 | 96 | # Save |
|
0 commit comments