Skip to content

Commit c75d17d

Browse files
update(bubble-basic): plotly — comprehensive quality review and improvement (#4263)
## Summary Updated **plotly** implementation for **bubble-basic**. **Changes:** comprehensive quality review and improvement ### Changes - Replaced generic x/y data with realistic, domain-relevant dataset - Improved visual design: white bubble edges, subtler grid, better alpha - Area-based bubble scaling per spec requirement - Meaningful axis labels with units - Enhanced library-specific feature usage - Quality self-assessment: see agent report ## 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 25ed938 commit c75d17d

2 files changed

Lines changed: 201 additions & 152 deletions

File tree

plots/bubble-basic/implementations/plotly.py

Lines changed: 54 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
""" pyplots.ai
22
bubble-basic: Basic Bubble Chart
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: 94/100 | Updated: 2026-02-16
55
"""
66

77
import numpy as np
@@ -16,93 +16,115 @@
1616
revenue = np.random.randn(n_companies) * 15 + 50
1717
revenue = np.clip(revenue, 10, 100)
1818

19-
# Growth rate (%) - y axis
19+
# Growth rate (%) - y axis, correlated with revenue
2020
growth = revenue * 0.3 + np.random.randn(n_companies) * 8 + 5
2121
growth = np.clip(growth, -5, 45)
2222

23-
# Market share (%) - bubble size
23+
# Market share (%) - bubble size and color
2424
market_share = np.abs(np.random.randn(n_companies) * 8 + 12)
2525
market_share = np.clip(market_share, 2, 35)
2626

27-
# Normalize size for bubble scaling (area-based perception)
28-
size_min, size_max = 20, 90
29-
size_normalized = (market_share - market_share.min()) / (market_share.max() - market_share.min())
30-
bubble_sizes = size_min + size_normalized * (size_max - size_min)
27+
# Add a few distinct outliers/clusters for storytelling
28+
# High-revenue, high-growth market leaders
29+
revenue[0], growth[0], market_share[0] = 92, 40, 33
30+
revenue[1], growth[1], market_share[1] = 85, 38, 28
31+
revenue[2], growth[2], market_share[2] = 88, 42, 31
32+
33+
# Low-revenue emerging players with moderate growth
34+
revenue[3], growth[3], market_share[3] = 15, 32, 5
35+
revenue[4], growth[4], market_share[4] = 18, 28, 4
36+
37+
# Bubble sizing via sizeref (Plotly's idiomatic area-based scaling)
38+
sizeref = 2.0 * max(market_share) / (55**2)
39+
40+
# Custom colorscale: ensure minimum value has visible contrast against white bg
41+
colorscale = [[0, "#6a9ec0"], [0.25, "#4a82a8"], [0.5, "#306998"], [0.75, "#1f4f78"], [1, "#0d2e4d"]]
3142

3243
# Plot
3344
fig = go.Figure()
3445

35-
# Main bubble scatter
3646
fig.add_trace(
3747
go.Scatter(
3848
x=revenue,
3949
y=growth,
4050
mode="markers",
4151
marker={
42-
"size": bubble_sizes,
43-
"color": "#306998",
44-
"opacity": 0.6,
45-
"line": {"width": 1.5, "color": "#1a3d5c"},
46-
"sizemode": "diameter",
52+
"size": market_share,
53+
"sizemode": "area",
54+
"sizeref": sizeref,
55+
"sizemin": 6,
56+
"color": market_share,
57+
"colorscale": colorscale,
58+
"colorbar": {
59+
"title": {"text": "Market<br>Share (%)", "font": {"size": 18}},
60+
"tickfont": {"size": 16},
61+
"thickness": 18,
62+
"len": 0.55,
63+
"y": 0.5,
64+
},
65+
"opacity": 0.78,
66+
"line": {"width": 1.5, "color": "white"},
4767
},
4868
text=[f"Market Share: {s:.1f}%" for s in market_share],
4969
hovertemplate="<b>Revenue:</b> $%{x:.1f}M<br><b>Growth:</b> %{y:.1f}%<br>%{text}<extra></extra>",
5070
showlegend=False,
5171
)
5272
)
5373

54-
# Size legend - representative bubbles
74+
# Size legend - representative bubbles positioned below colorbar
5575
legend_sizes = [5, 15, 30]
56-
legend_bubble_sizes = [
57-
size_min + ((s - market_share.min()) / (market_share.max() - market_share.min())) * (size_max - size_min)
58-
for s in legend_sizes
59-
]
60-
61-
for label_size, bubble_size in zip(legend_sizes, legend_bubble_sizes, strict=True):
76+
for label_size in legend_sizes:
6277
fig.add_trace(
6378
go.Scatter(
6479
x=[None],
6580
y=[None],
6681
mode="markers",
6782
marker={
68-
"size": bubble_size,
83+
"size": label_size,
84+
"sizemode": "area",
85+
"sizeref": sizeref,
86+
"sizemin": 4,
6987
"color": "#306998",
70-
"opacity": 0.6,
71-
"line": {"width": 1.5, "color": "#1a3d5c"},
88+
"opacity": 0.78,
89+
"line": {"width": 1.5, "color": "white"},
7290
},
7391
name=f"{label_size}%",
7492
showlegend=True,
7593
)
7694
)
7795

78-
# Layout
96+
# Layout - balanced margins, legend below colorbar
7997
fig.update_layout(
8098
title={"text": "bubble-basic · plotly · pyplots.ai", "font": {"size": 32}, "x": 0.5, "xanchor": "center"},
8199
xaxis={
82100
"title": {"text": "Revenue ($ millions)", "font": {"size": 24}},
83101
"tickfont": {"size": 18},
84-
"gridcolor": "rgba(0,0,0,0.1)",
102+
"gridcolor": "rgba(0,0,0,0.08)",
85103
"gridwidth": 1,
104+
"zeroline": False,
86105
},
87106
yaxis={
88107
"title": {"text": "Growth Rate (%)", "font": {"size": 24}},
89108
"tickfont": {"size": 18},
90-
"gridcolor": "rgba(0,0,0,0.1)",
109+
"gridcolor": "rgba(0,0,0,0.08)",
91110
"gridwidth": 1,
111+
"zeroline": False,
92112
},
93113
template="plotly_white",
94114
legend={
95115
"title": {"text": "Market Share", "font": {"size": 18}},
96116
"font": {"size": 16},
97-
"x": 1.02,
98-
"y": 0.98,
117+
"x": 1.12,
118+
"y": 0.02,
99119
"xanchor": "left",
100-
"yanchor": "top",
101-
"bgcolor": "rgba(255,255,255,0.8)",
102-
"bordercolor": "rgba(0,0,0,0.2)",
120+
"yanchor": "bottom",
121+
"bgcolor": "rgba(255,255,255,0.85)",
122+
"bordercolor": "rgba(0,0,0,0.12)",
103123
"borderwidth": 1,
104124
},
105125
margin={"l": 100, "r": 180, "t": 120, "b": 100},
126+
plot_bgcolor="white",
127+
paper_bgcolor="white",
106128
)
107129

108130
# Save

0 commit comments

Comments
 (0)