Skip to content

Commit 841524b

Browse files
feat(letsplot): implement scatter-annotated (#2831)
## Implementation: `scatter-annotated` - letsplot Implements the **letsplot** version of `scatter-annotated`. **File:** `plots/scatter-annotated/implementations/letsplot.py` --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/pyplots/actions/runs/20602455677)* --------- 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 14df5ff commit 841524b

2 files changed

Lines changed: 99 additions & 0 deletions

File tree

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
""" pyplots.ai
2+
scatter-annotated: Annotated Scatter Plot with Text Labels
3+
Library: letsplot 4.8.2 | Python 3.13.11
4+
Quality: 91/100 | Created: 2025-12-30
5+
"""
6+
7+
import numpy as np
8+
import pandas as pd
9+
from lets_plot import *
10+
11+
12+
LetsPlot.setup_html()
13+
14+
# Data - Company performance metrics (neutral business context)
15+
np.random.seed(42)
16+
17+
companies = [
18+
"Acme Corp",
19+
"TechFlow",
20+
"DataSys",
21+
"CloudNet",
22+
"NeuraTech",
23+
"ByteWorks",
24+
"InfoPlex",
25+
"CyberDyn",
26+
"QuantumAI",
27+
"LogiCore",
28+
"MegaSoft",
29+
"SynergyX",
30+
"DigiHub",
31+
"SmartScale",
32+
"CoreLogic",
33+
]
34+
35+
# Revenue (millions) and growth rate (percentage)
36+
revenue = np.random.uniform(50, 500, len(companies))
37+
growth = np.random.uniform(5, 45, len(companies))
38+
39+
# Add some outliers for visual interest
40+
revenue[4] = 480 # NeuraTech - high revenue
41+
growth[4] = 42 # NeuraTech - high growth
42+
revenue[8] = 120 # QuantumAI - low revenue
43+
growth[8] = 48 # QuantumAI - exceptional growth (startup)
44+
revenue[10] = 520 # MegaSoft - highest revenue
45+
growth[10] = 8 # MegaSoft - low growth (mature company)
46+
47+
df = pd.DataFrame({"company": companies, "revenue": revenue, "growth": growth})
48+
49+
# Create annotated scatter plot
50+
plot = (
51+
ggplot(df, aes(x="revenue", y="growth"))
52+
+ geom_point(size=8, color="#306998", alpha=0.7)
53+
+ geom_text(aes(label="company"), size=12, nudge_y=2.5, color="#333333")
54+
+ scale_y_continuous(limits=[0, 55])
55+
+ labs(
56+
x="Annual Revenue ($ millions)",
57+
y="Year-over-Year Growth (%)",
58+
title="scatter-annotated · lets-plot · pyplots.ai",
59+
)
60+
+ theme_minimal()
61+
+ theme(
62+
plot_title=element_text(size=24, face="bold"),
63+
axis_title=element_text(size=20),
64+
axis_text=element_text(size=16),
65+
panel_grid_major=element_line(color="#cccccc", size=0.5),
66+
panel_grid_minor=element_line(color="#eeeeee", size=0.3),
67+
)
68+
+ ggsize(1600, 900)
69+
)
70+
71+
# Save as PNG (scale 3x for 4800x2700 px)
72+
ggsave(plot, "plot.png", path=".", scale=3)
73+
74+
# Save interactive HTML version
75+
ggsave(plot, "plot.html", path=".")
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
library: letsplot
2+
specification_id: scatter-annotated
3+
created: '2025-12-30T17:53:28Z'
4+
updated: '2025-12-30T18:05:30Z'
5+
generated_by: claude-opus-4-5-20251101
6+
workflow_run: 20602455677
7+
issue: 0
8+
python_version: 3.13.11
9+
library_version: 4.8.2
10+
preview_url: https://storage.googleapis.com/pyplots-images/plots/scatter-annotated/letsplot/plot.png
11+
preview_thumb: https://storage.googleapis.com/pyplots-images/plots/scatter-annotated/letsplot/plot_thumb.png
12+
preview_html: https://storage.googleapis.com/pyplots-images/plots/scatter-annotated/letsplot/plot.html
13+
quality_score: 91
14+
review:
15+
strengths:
16+
- Clean, readable visualization with all 15 company labels clearly visible
17+
- Good use of geom_text with nudge_y for label positioning
18+
- Appropriate point size and alpha for data density
19+
- Realistic business scenario with meaningful outliers (startup high-growth, mature
20+
low-growth)
21+
- Correct title format and axis labels with units
22+
weaknesses:
23+
- Some label pairs are close together (ByteWorks/SmartScale, DataSys/LogiCore/CloudNet
24+
region) - could benefit from adjustText-like positioning if available in lets-plot

0 commit comments

Comments
 (0)