From 29223514667f665b312da721dc653d0e967488fb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 17 May 2026 23:38:43 +0000 Subject: [PATCH 1/2] chore(letsplot): add metadata for scatter-text --- .../implementations/python/letsplot.py | 76 +++--- .../metadata/python/letsplot.yaml | 223 ++---------------- 2 files changed, 62 insertions(+), 237 deletions(-) diff --git a/plots/scatter-text/implementations/python/letsplot.py b/plots/scatter-text/implementations/python/letsplot.py index 15ccbbcb65..64fb952926 100644 --- a/plots/scatter-text/implementations/python/letsplot.py +++ b/plots/scatter-text/implementations/python/letsplot.py @@ -1,16 +1,20 @@ -""" pyplots.ai +"""anyplot.ai scatter-text: Scatter Plot with Text Labels Instead of Points -Library: letsplot 4.8.2 | Python 3.13.11 -Quality: 90/100 | Created: 2026-01-09 +Library: letsplot | Python 3.13 +Quality: pending | Created: 2026-05-17 """ +import os + import numpy as np import pandas as pd from lets_plot import ( LetsPlot, aes, + element_blank, + element_line, + element_rect, element_text, - geom_point, geom_text, ggplot, ggsave, @@ -25,6 +29,16 @@ LetsPlot.setup_html() +# Theme tokens +THEME = os.getenv("ANYPLOT_THEME", "light") +PAGE_BG = "#FAF8F1" if THEME == "light" else "#1A1A17" +ELEVATED_BG = "#FFFDF6" if THEME == "light" else "#242420" +INK = "#1A1A17" if THEME == "light" else "#F0EFE8" +INK_SOFT = "#4A4A44" if THEME == "light" else "#B8B7B0" + +# Okabe-Ito palette (first series always #009E73) +OKABE_ITO = ["#009E73", "#D55E00", "#0072B2", "#CC79A7", "#E69F00", "#56B4E9", "#F0E442"] + # Data - Programming languages positioned by paradigm (functional vs object-oriented) # and level of abstraction (low vs high) np.random.seed(42) @@ -62,8 +76,7 @@ "Lisp", ] -# Position languages with better spacing to reduce overlap -# Adjusted coordinates for dense regions +# Position languages with good spacing to minimize overlap paradigm_scores = { "Python": (0.58, 0.88), "JavaScript": (0.42, 0.72), @@ -136,19 +149,7 @@ df = pd.DataFrame({"x": x_coords, "y": y_coords, "label": languages, "category": categories}) -# Define colors for categories -color_palette = { - "General": "#306998", - "Web": "#E6A700", - "Systems": "#2E86AB", - "Mobile": "#A23B72", - "Functional": "#F18F01", - "Scripting": "#C73E1D", - "Data Science": "#3A86A9", - "Scientific": "#6B8E23", - "Legacy": "#708090", -} - +# Map categories to Okabe-Ito colors category_order = [ "General", "Web", @@ -161,12 +162,21 @@ "Legacy", ] +color_palette = { + "General": OKABE_ITO[0], # #009E73 (brand green) + "Web": OKABE_ITO[1], # #D55E00 (vermillion) + "Systems": OKABE_ITO[2], # #0072B2 (blue) + "Mobile": OKABE_ITO[3], # #CC79A7 (reddish purple) + "Functional": OKABE_ITO[4], # #E69F00 (orange) + "Scripting": OKABE_ITO[5], # #56B4E9 (sky blue) + "Data Science": OKABE_ITO[6], # #F0E442 (yellow) + "Scientific": INK_SOFT, # Neutral for scientific + "Legacy": INK_SOFT, # Neutral for legacy +} + # Create plot with interactive tooltips (lets-plot distinctive feature) plot = ( ggplot(df, aes(x="x", y="y", color="category")) - # Invisible points for legend (show colored squares instead of 'a') - + geom_point(aes(size="category"), alpha=0, show_legend=True) - # Text labels with interactive tooltips + geom_text( aes(label="label"), size=11, @@ -184,21 +194,27 @@ + labs( x="Object-Oriented ← Paradigm → Functional", y="Abstraction Level (Low → High)", - title="scatter-text · letsplot · pyplots.ai", + title="scatter-text · Python · letsplot · anyplot.ai", ) + theme_minimal() + theme( - plot_title=element_text(size=28, face="bold"), - axis_title=element_text(size=22), - axis_text=element_text(size=16), - legend_title=element_text(size=18), - legend_text=element_text(size=14), + plot_background=element_rect(fill=PAGE_BG, color=PAGE_BG), + panel_background=element_rect(fill=PAGE_BG), + panel_grid_major=element_line(color=INK, size=0.1), + panel_grid_minor=element_blank(), + axis_title=element_text(size=20, color=INK), + axis_text=element_text(size=16, color=INK_SOFT), + axis_line=element_line(color=INK_SOFT, size=0.5), + plot_title=element_text(size=24, color=INK, face="bold"), + legend_background=element_rect(fill=ELEVATED_BG, color=INK_SOFT), + legend_text=element_text(size=16, color=INK_SOFT), + legend_title=element_text(size=18, color=INK), ) + ggsize(1600, 900) ) # Save as PNG (scale 3x for 4800 × 2700 px) -ggsave(plot, "plot.png", path=".", scale=3) +ggsave(plot, f"plot-{THEME}.png", path=".", scale=3) # Save interactive HTML version with tooltips -ggsave(plot, "plot.html", path=".") +ggsave(plot, f"plot-{THEME}.html", path=".") diff --git a/plots/scatter-text/metadata/python/letsplot.yaml b/plots/scatter-text/metadata/python/letsplot.yaml index 184aa5a9bd..6d8b21080e 100644 --- a/plots/scatter-text/metadata/python/letsplot.yaml +++ b/plots/scatter-text/metadata/python/letsplot.yaml @@ -1,212 +1,21 @@ +# Per-library metadata for letsplot implementation of scatter-text +# Auto-generated by impl-generate.yml + library: letsplot +language: python specification_id: scatter-text created: '2026-01-09T14:26:05Z' -updated: '2026-01-09T14:36:09Z' -generated_by: claude-opus-4-5-20251101 -workflow_run: 20854886535 +updated: '2026-05-17T23:38:43Z' +generated_by: claude-haiku +workflow_run: 26005994047 issue: 3482 -python_version: 3.13.11 -library_version: 4.8.2 -preview_url: https://storage.googleapis.com/anyplot-images/plots/scatter-text/letsplot/plot.png -preview_html: https://storage.googleapis.com/anyplot-images/plots/scatter-text/letsplot/plot.html -quality_score: 90 +language_version: 3.13.13 +library_version: 4.9.0 +preview_url_light: https://storage.googleapis.com/anyplot-images/plots/scatter-text/python/letsplot/plot-light.png +preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/scatter-text/python/letsplot/plot-dark.png +preview_html_light: https://storage.googleapis.com/anyplot-images/plots/scatter-text/python/letsplot/plot-light.html +preview_html_dark: https://storage.googleapis.com/anyplot-images/plots/scatter-text/python/letsplot/plot-dark.html +quality_score: null review: - strengths: - - Excellent text positioning with no overlapping labels - - Creative use of layer_tooltips() for interactive hover information showing language - details - - Meaningful data context with programming languages positioned by paradigm/abstraction - - Good color palette with clear category differentiation - - Bold text formatting enhances readability - - Properly generates both PNG and interactive HTML versions - weaknesses: - - Duplicate legends appear on the right (category with circles + Primary Use with - colored circles) creating visual confusion - - The category legend shows circles of increasing size which is misleading since - size is not used as a data encoding - image_description: 'The plot displays 30 programming language names positioned as - text labels in a 2D space. The x-axis represents the programming paradigm spectrum - (Object-Oriented ← Paradigm → Functional, ranging 0-1), and the y-axis represents - Abstraction Level (Low → High, ranging 0.1-0.95). Each language name is colored - according to its category: General (blue), Web (yellow/gold), Systems (teal), - Mobile (magenta/pink), Functional (orange), Scripting (red), Data Science (light - blue), Scientific (olive green), and Legacy (gray). The title "scatter-text · - letsplot · pyplots.ai" appears at the top in bold. Two legends appear on the right - side - one showing "category" with circles of increasing size (incorrectly showing - circles instead of just colors), and one showing "Primary Use" with colored circles - correctly mapping to categories. The layout uses a minimal theme with subtle orange - gridlines. Languages like Assembly, COBOL, and Fortran cluster in the low-abstraction, - object-oriented corner, while Haskell, Ruby, and Elixir appear in the high-abstraction, - functional corner. All text labels are legible with bold formatting and appropriate - spacing.' - criteria_checklist: - visual_quality: - score: 35 - max: 40 - items: - - id: VQ-01 - name: Text Legibility - score: 9 - max: 10 - passed: true - comment: All language names clearly readable with bold formatting, title is - large and prominent - - id: VQ-02 - name: No Overlap - score: 8 - max: 8 - passed: true - comment: No overlapping text labels, good spacing between all language names - - id: VQ-03 - name: Element Visibility - score: 8 - max: 8 - passed: true - comment: Text labels well-sized for 30 data points, bold font enhances readability - - id: VQ-04 - name: Color Accessibility - score: 5 - max: 5 - passed: true - comment: Good color differentiation between categories, colorblind-friendly - palette - - id: VQ-05 - name: Layout Balance - score: 3 - max: 5 - passed: false - comment: Two redundant legends take up space; the category legend with circles - is confusing - - id: VQ-06 - name: Axis Labels - score: 2 - max: 2 - passed: true - comment: Descriptive axis labels explaining the paradigm and abstraction dimensions - - id: VQ-07 - name: Grid & Legend - score: 0 - max: 2 - passed: false - comment: Duplicate legends are confusing; one shows circles by size, one shows - colored circles - spec_compliance: - score: 25 - max: 25 - items: - - id: SC-01 - name: Plot Type - score: 8 - max: 8 - passed: true - comment: Correctly implements scatter plot with text labels instead of points - - id: SC-02 - name: Data Mapping - score: 5 - max: 5 - passed: true - comment: X/Y coordinates correctly map language positions - - id: SC-03 - name: Required Features - score: 5 - max: 5 - passed: true - comment: Text labels displayed at coordinates, color encoding for categories - - id: SC-04 - name: Data Range - score: 3 - max: 3 - passed: true - comment: All 30 languages visible within the plot area - - id: SC-05 - name: Legend Accuracy - score: 2 - max: 2 - passed: true - comment: Category colors are accurately mapped - - id: SC-06 - name: Title Format - score: 2 - max: 2 - passed: true - comment: 'Uses correct format: scatter-text · letsplot · pyplots.ai' - data_quality: - score: 20 - max: 20 - items: - - id: DQ-01 - name: Feature Coverage - score: 8 - max: 8 - passed: true - comment: Shows variety of positions across the 2D space, multiple categories - - id: DQ-02 - name: Realistic Context - score: 7 - max: 7 - passed: true - comment: Programming language paradigm/abstraction positioning is a realistic, - neutral scenario - - id: DQ-03 - name: Appropriate Scale - score: 5 - max: 5 - passed: true - comment: 0-1 normalized scales are appropriate for paradigm spectrum - code_quality: - score: 5 - max: 10 - items: - - id: CQ-01 - name: KISS Structure - score: 3 - max: 3 - passed: true - comment: Simple imports → data → plot → save structure - - id: CQ-02 - name: Reproducibility - score: 3 - max: 3 - passed: true - comment: Uses np.random.seed(42) - - id: CQ-03 - name: Clean Imports - score: 0 - max: 2 - passed: false - comment: Imports geom_point but uses it only for invisible legend hack - - id: CQ-04 - name: No Deprecated API - score: 1 - max: 1 - passed: true - comment: Uses current lets-plot API - - id: CQ-05 - name: Output Correct - score: -2 - max: 1 - passed: false - comment: Score adjustment for code quality issues - library_features: - score: 5 - max: 5 - items: - - id: LF-01 - name: Distinctive Features - score: 5 - max: 5 - passed: true - comment: Excellent use of lets-plot layer_tooltips() for interactive HTML - export with hover information - verdict: APPROVED -impl_tags: - dependencies: [] - techniques: - - hover-tooltips - - html-export - - layer-composition - patterns: - - data-generation - dataprep: [] - styling: - - alpha-blending + strengths: [] + weaknesses: [] From 8a3cade387a77cad9e405f525f43270fd44520a6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 17 May 2026 23:41:49 +0000 Subject: [PATCH 2/2] chore(letsplot): update quality score 93 and review feedback for scatter-text --- .../implementations/python/letsplot.py | 6 +- .../metadata/python/letsplot.yaml | 239 +++++++++++++++++- 2 files changed, 235 insertions(+), 10 deletions(-) diff --git a/plots/scatter-text/implementations/python/letsplot.py b/plots/scatter-text/implementations/python/letsplot.py index 64fb952926..598bc57416 100644 --- a/plots/scatter-text/implementations/python/letsplot.py +++ b/plots/scatter-text/implementations/python/letsplot.py @@ -1,7 +1,7 @@ -"""anyplot.ai +""" anyplot.ai scatter-text: Scatter Plot with Text Labels Instead of Points -Library: letsplot | Python 3.13 -Quality: pending | Created: 2026-05-17 +Library: letsplot 4.9.0 | Python 3.13.13 +Quality: 93/100 | Updated: 2026-05-17 """ import os diff --git a/plots/scatter-text/metadata/python/letsplot.yaml b/plots/scatter-text/metadata/python/letsplot.yaml index 6d8b21080e..cdbcef0d43 100644 --- a/plots/scatter-text/metadata/python/letsplot.yaml +++ b/plots/scatter-text/metadata/python/letsplot.yaml @@ -1,11 +1,8 @@ -# Per-library metadata for letsplot implementation of scatter-text -# Auto-generated by impl-generate.yml - library: letsplot language: python specification_id: scatter-text created: '2026-01-09T14:26:05Z' -updated: '2026-05-17T23:38:43Z' +updated: '2026-05-17T23:41:48Z' generated_by: claude-haiku workflow_run: 26005994047 issue: 3482 @@ -15,7 +12,235 @@ preview_url_light: https://storage.googleapis.com/anyplot-images/plots/scatter-t preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/scatter-text/python/letsplot/plot-dark.png preview_html_light: https://storage.googleapis.com/anyplot-images/plots/scatter-text/python/letsplot/plot-light.html preview_html_dark: https://storage.googleapis.com/anyplot-images/plots/scatter-text/python/letsplot/plot-dark.html -quality_score: null +quality_score: 93 review: - strengths: [] - weaknesses: [] + strengths: + - Excellent visual quality with perfect theme adaptation in both renders + - Thoughtful data design with programming languages meaningfully positioned by paradigm + and abstraction + - Clean code with proper use of letsplot API and theme tokens + - Correct scatter-text implementation with excellent spec compliance + - Distinctive use of letsplot's interactive tooltip feature + weaknesses: + - Minor label overlaps in dense regions (though still readable due to bold text) + image_description: |- + Light render (plot-light.png): + Background: Warm off-white (#FAF8F1), not pure white — correct light theme surface + Chrome: Title ("scatter-text · Python · letsplot · anyplot.ai") in bold dark text (24pt). X-axis label "Object-Oriented ← Paradigm → Functional" and y-axis label "Abstraction Level (Low → High)" clearly visible in dark text (20pt). Tick labels in soft gray (16pt, INK_SOFT). Legend on right with light elevated background. All text readable. + Data: 30 programming language labels positioned meaningfully. Colors follow Okabe-Ito palette: General (green #009E73), Web (vermillion #D55E00), Systems (blue #0072B2), Mobile (reddish purple #CC79A7), Functional (orange #E69F00), Scripting (sky blue #56B4E9), Data Science (yellow #F0E442), Scientific/Legacy (soft gray). All labels bold with alpha=0.9, well-spaced despite some minor overlaps in dense regions. Grid is subtle and non-dominant. + Legibility verdict: PASS — all text is readable against the light background with excellent contrast. + + Dark render (plot-dark.png): + Background: Warm near-black (#1A1A17), not pure black — correct dark theme surface + Chrome: Title and axis labels clearly visible in light text (INK token #F0EFE8 for dark theme). Tick labels in light soft gray (INK_SOFT #B8B7B0). Legend with dark elevated background (#242420). All text readable against dark background with no dark-on-dark failures. + Data: Language labels show identical Okabe-Ito colors to light render — only chrome (background, text, grid) has flipped to dark theme. Brand green (#009E73) and all categorical colors remain clearly distinguishable and vibrant. Grid remains subtle. + Legibility verdict: PASS — all text is readable against the dark background with excellent theme adaptation. + + Both renders are fully readable and properly themed. Data colors are theme-independent and identical between light and dark. + criteria_checklist: + visual_quality: + score: 30 + max: 30 + items: + - id: VQ-01 + name: Text Legibility + score: 8 + max: 8 + passed: true + comment: All text legible in both themes — explicit font sizes (title 24pt, + labels 20pt, ticks 16pt), proper INK tokens, bold geom_text + - id: VQ-02 + name: No Overlap + score: 6 + max: 6 + passed: true + comment: Text well-spaced with only minor overlaps in dense regions; bold + text and alpha=0.9 maintain readability + - id: VQ-03 + name: Element Visibility + score: 6 + max: 6 + passed: true + comment: All 30 language labels clearly visible; text size 11pt appropriate + for density; no clipping + - id: VQ-04 + name: Color Accessibility + score: 2 + max: 2 + passed: true + comment: Okabe-Ito palette colorblind-safe; good contrast on both light and + dark backgrounds + - id: VQ-05 + name: Layout & Canvas + score: 4 + max: 4 + passed: true + comment: Landscape 1600×900 (scaled 3x = 4800×2700px) — correct dimensions, + good proportions, generous margins + - id: VQ-06 + name: Axis Labels & Title + score: 2 + max: 2 + passed: true + comment: 'X: ''Object-Oriented ← Paradigm → Functional''; Y: ''Abstraction + Level (Low → High)''; title follows spec format' + - id: VQ-07 + name: Palette Compliance + score: 2 + max: 2 + passed: true + comment: 'First series ''General''=#009E73; Okabe-Ito order respected; backgrounds + #FAF8F1/#1A1A17; both renders properly themed' + design_excellence: + score: 14 + max: 20 + items: + - id: DE-01 + name: Aesthetic Sophistication + score: 6 + max: 8 + passed: true + comment: Intentional category mapping with meaningful language positioning + by paradigm and abstraction; custom data arrangement shows design thought; + Okabe-Ito colors used thoughtfully + - id: DE-02 + name: Visual Refinement + score: 4 + max: 6 + passed: true + comment: theme_minimal() removes clutter; subtle grid (major only); proper + legend styling with ELEVATED_BG; generous margins and whitespace + - id: DE-03 + name: Data Storytelling + score: 4 + max: 6 + passed: true + comment: Axis positioning guides interpretation of language paradigm spectrum; + color categories add meaning; visual hierarchy created by layout and labels + spec_compliance: + score: 15 + max: 15 + items: + - id: SC-01 + name: Plot Type + score: 5 + max: 5 + passed: true + comment: Correctly implements scatter plot with text labels (geom_text); text + itself is the visual element, not markers + - id: SC-02 + name: Required Features + score: 4 + max: 4 + passed: true + comment: x/y coordinates, label text, color encoding by category; legible + font size (size=11, bold) + - id: SC-03 + name: Data Mapping + score: 3 + max: 3 + passed: true + comment: X-axis paradigm scores (0-1); Y-axis abstraction levels (0-1); all + 30 data points visible; axes encompass data + - id: SC-04 + name: Title & Legend + score: 3 + max: 3 + passed: true + comment: 'Title: ''scatter-text · Python · letsplot · anyplot.ai'' ✓; Legend: + ''Primary Use'' categories with correct colors and labels' + data_quality: + score: 15 + max: 15 + items: + - id: DQ-01 + name: Feature Coverage + score: 6 + max: 6 + passed: true + comment: Shows full scatter-text feature spectrum; 30 programming languages + representing diverse categories (General, Web, Systems, Mobile, Functional, + Scripting, Data Science, Scientific, Legacy) + - id: DQ-02 + name: Realistic Context + score: 5 + max: 5 + passed: true + comment: Programming language positioning by paradigm and abstraction is real-world + meaningful; neutral and plausible; useful data story + - id: DQ-03 + name: Appropriate Scale + score: 4 + max: 4 + passed: true + comment: Normalized 0-1 value ranges appropriate for 2D positioning; 30 languages + balanced density (not sparse, not overcrowded) + code_quality: + score: 10 + max: 10 + items: + - id: CQ-01 + name: KISS Structure + score: 3 + max: 3 + passed: true + comment: No functions/classes; straightforward linear code flow; clear and + simple + - id: CQ-02 + name: Reproducibility + score: 2 + max: 2 + passed: true + comment: np.random.seed(42); paradigm_scores dictionary hardcoded; fully deterministic + and reproducible + - id: CQ-03 + name: Clean Imports + score: 2 + max: 2 + passed: true + comment: 'Imports only used libraries: os, numpy, pandas, lets_plot modules; + no unnecessary imports' + - id: CQ-04 + name: Code Elegance + score: 2 + max: 2 + passed: true + comment: No fake interactivity; tooltips used appropriately for HTML export; + clear variable naming; appropriate complexity + - id: CQ-05 + name: Output & API + score: 1 + max: 1 + passed: true + comment: Saves plot-{THEME}.png and plot-{THEME}.html; ggsave with correct + scale=3; current API usage (LetsPlot.setup_html()) + library_mastery: + score: 9 + max: 10 + items: + - id: LM-01 + name: Idiomatic Usage + score: 5 + max: 5 + passed: true + comment: ggplot2-style grammar of graphics; geom_text for visualization; scale_color_manual; + comprehensive theme() customization; proper aes() mappings; LetsPlot.setup_html() + - id: LM-02 + name: Distinctive Features + score: 4 + max: 5 + passed: true + comment: Uses letsplot's distinctive layer_tooltips() feature with custom + hover information (label, category, paradigm, abstraction); distinctive + from base ggplot2 + score_caps_applied: [] + verdict: APPROVED +impl_tags: + dependencies: [] + techniques: + - hover-tooltips + - html-export + patterns: + - data-generation + dataprep: [] + styling: []