diff --git a/plots/scatter-annotated/implementations/letsplot.py b/plots/scatter-annotated/implementations/letsplot.py new file mode 100644 index 0000000000..1a8cdceae2 --- /dev/null +++ b/plots/scatter-annotated/implementations/letsplot.py @@ -0,0 +1,75 @@ +""" pyplots.ai +scatter-annotated: Annotated Scatter Plot with Text Labels +Library: letsplot 4.8.2 | Python 3.13.11 +Quality: 91/100 | Created: 2025-12-30 +""" + +import numpy as np +import pandas as pd +from lets_plot import * + + +LetsPlot.setup_html() + +# Data - Company performance metrics (neutral business context) +np.random.seed(42) + +companies = [ + "Acme Corp", + "TechFlow", + "DataSys", + "CloudNet", + "NeuraTech", + "ByteWorks", + "InfoPlex", + "CyberDyn", + "QuantumAI", + "LogiCore", + "MegaSoft", + "SynergyX", + "DigiHub", + "SmartScale", + "CoreLogic", +] + +# Revenue (millions) and growth rate (percentage) +revenue = np.random.uniform(50, 500, len(companies)) +growth = np.random.uniform(5, 45, len(companies)) + +# Add some outliers for visual interest +revenue[4] = 480 # NeuraTech - high revenue +growth[4] = 42 # NeuraTech - high growth +revenue[8] = 120 # QuantumAI - low revenue +growth[8] = 48 # QuantumAI - exceptional growth (startup) +revenue[10] = 520 # MegaSoft - highest revenue +growth[10] = 8 # MegaSoft - low growth (mature company) + +df = pd.DataFrame({"company": companies, "revenue": revenue, "growth": growth}) + +# Create annotated scatter plot +plot = ( + ggplot(df, aes(x="revenue", y="growth")) + + geom_point(size=8, color="#306998", alpha=0.7) + + geom_text(aes(label="company"), size=12, nudge_y=2.5, color="#333333") + + scale_y_continuous(limits=[0, 55]) + + labs( + x="Annual Revenue ($ millions)", + y="Year-over-Year Growth (%)", + title="scatter-annotated · lets-plot · pyplots.ai", + ) + + theme_minimal() + + theme( + plot_title=element_text(size=24, face="bold"), + axis_title=element_text(size=20), + axis_text=element_text(size=16), + panel_grid_major=element_line(color="#cccccc", size=0.5), + panel_grid_minor=element_line(color="#eeeeee", size=0.3), + ) + + ggsize(1600, 900) +) + +# Save as PNG (scale 3x for 4800x2700 px) +ggsave(plot, "plot.png", path=".", scale=3) + +# Save interactive HTML version +ggsave(plot, "plot.html", path=".") diff --git a/plots/scatter-annotated/metadata/letsplot.yaml b/plots/scatter-annotated/metadata/letsplot.yaml new file mode 100644 index 0000000000..b081d3f439 --- /dev/null +++ b/plots/scatter-annotated/metadata/letsplot.yaml @@ -0,0 +1,24 @@ +library: letsplot +specification_id: scatter-annotated +created: '2025-12-30T17:53:28Z' +updated: '2025-12-30T18:05:30Z' +generated_by: claude-opus-4-5-20251101 +workflow_run: 20602455677 +issue: 0 +python_version: 3.13.11 +library_version: 4.8.2 +preview_url: https://storage.googleapis.com/pyplots-images/plots/scatter-annotated/letsplot/plot.png +preview_thumb: https://storage.googleapis.com/pyplots-images/plots/scatter-annotated/letsplot/plot_thumb.png +preview_html: https://storage.googleapis.com/pyplots-images/plots/scatter-annotated/letsplot/plot.html +quality_score: 91 +review: + strengths: + - Clean, readable visualization with all 15 company labels clearly visible + - Good use of geom_text with nudge_y for label positioning + - Appropriate point size and alpha for data density + - Realistic business scenario with meaningful outliers (startup high-growth, mature + low-growth) + - Correct title format and axis labels with units + weaknesses: + - Some label pairs are close together (ByteWorks/SmartScale, DataSys/LogiCore/CloudNet + region) - could benefit from adjustText-like positioning if available in lets-plot