Skip to content

Commit 0996de9

Browse files
feat(plotnine): implement scatter-annotated (#2797)
## Implementation: `scatter-annotated` - plotnine Implements the **plotnine** version of `scatter-annotated`. **File:** `plots/scatter-annotated/implementations/plotnine.py` --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/pyplots/actions/runs/20602453182)* --------- 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 adbb9de commit 0996de9

2 files changed

Lines changed: 92 additions & 0 deletions

File tree

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
""" pyplots.ai
2+
scatter-annotated: Annotated Scatter Plot with Text Labels
3+
Library: plotnine 0.15.2 | Python 3.13.11
4+
Quality: 92/100 | Created: 2025-12-30
5+
"""
6+
7+
import numpy as np
8+
import pandas as pd
9+
from plotnine import (
10+
aes,
11+
element_text,
12+
geom_point,
13+
geom_text,
14+
ggplot,
15+
labs,
16+
scale_x_continuous,
17+
scale_y_continuous,
18+
theme,
19+
theme_minimal,
20+
)
21+
22+
23+
# Data - Company performance metrics (fewer points to avoid label overlap)
24+
np.random.seed(42)
25+
26+
companies = [
27+
"TechCorp",
28+
"DataFlow",
29+
"CloudNet",
30+
"AI Labs",
31+
"InfoSys",
32+
"AppWorks",
33+
"SoftCore",
34+
"CodeBase",
35+
"SmartSys",
36+
"WebDev",
37+
]
38+
39+
# Revenue (millions) and Profit Margin (percentage) - spread out to avoid overlap
40+
revenue = np.array([35, 95, 140, 200, 65, 170, 110, 55, 125, 80])
41+
profit_margin = np.array([6, 12, 18, 23, 9, 20, 15, 8, 16, 11])
42+
43+
# Add small variation
44+
revenue = revenue + np.random.uniform(-3, 3, len(companies))
45+
profit_margin = profit_margin + np.random.uniform(-0.5, 0.5, len(companies))
46+
47+
df = pd.DataFrame({"company": companies, "revenue": revenue, "profit_margin": profit_margin})
48+
49+
# Create plot
50+
plot = (
51+
ggplot(df, aes(x="revenue", y="profit_margin"))
52+
+ geom_point(size=6, alpha=0.7, color="#306998")
53+
+ geom_text(aes(label="company"), size=11, nudge_y=0.9, color="#333333", va="bottom")
54+
+ labs(x="Annual Revenue ($ Millions)", y="Profit Margin (%)", title="scatter-annotated · plotnine · pyplots.ai")
55+
+ scale_x_continuous(limits=(20, 220))
56+
+ scale_y_continuous(limits=(4, 26))
57+
+ theme_minimal()
58+
+ theme(
59+
figure_size=(16, 9),
60+
text=element_text(size=14),
61+
axis_title=element_text(size=20),
62+
axis_text=element_text(size=16),
63+
plot_title=element_text(size=24),
64+
)
65+
)
66+
67+
# Save
68+
plot.save("plot.png", dpi=300, verbose=False)
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
library: plotnine
2+
specification_id: scatter-annotated
3+
created: '2025-12-30T17:47:43Z'
4+
updated: '2025-12-30T17:53:48Z'
5+
generated_by: claude-opus-4-5-20251101
6+
workflow_run: 20602453182
7+
issue: 0
8+
python_version: 3.13.11
9+
library_version: 0.15.2
10+
preview_url: https://storage.googleapis.com/pyplots-images/plots/scatter-annotated/plotnine/plot.png
11+
preview_thumb: https://storage.googleapis.com/pyplots-images/plots/scatter-annotated/plotnine/plot_thumb.png
12+
preview_html: null
13+
quality_score: 92
14+
review:
15+
strengths:
16+
- Excellent label placement with nudge_y preventing overlap
17+
- Clean minimal theme appropriate for annotated scatter plot
18+
- Well-chosen data spread prevents label collisions
19+
- Proper use of plotnine grammar of graphics syntax
20+
- Appropriate font sizing for 4800x2700 resolution
21+
weaknesses:
22+
- Grid lines could be more subtle (add alpha parameter if possible)
23+
- Point size could be slightly larger for only 10 data points (size=8-10 would be
24+
more visible)

0 commit comments

Comments
 (0)