From 4c00f7acb9171d51475913faddf3a4582a638304 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 9 Jun 2026 23:28:19 +0000 Subject: [PATCH 1/5] feat(letsplot): implement scatter-connected-temporal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Regen from quality 90. Addressed: - Canvas: fixed ggsize(1600,900) scale=3 → ggsize(800,450) scale=4 (3200×1800) - Theme: added ANYPLOT_THEME env var support; full theme-adaptive chrome - Background: #FAFBFC → PAGE_BG (#FAF8F1 light / #1A1A17 dark) - Colors: custom blue gradient → Imprint sequential (#009E73 → #4467A3) - Text: hardcoded colors → INK/INK_SOFT theme tokens - Font sizes: scaled down to style-guide values (title 16, axis 12, tick 10) - Title: corrected format with "python" token and "anyplot.ai" - Save: plot.png → plot-{THEME}.png + plot-{THEME}.html with path="." - Annotations: geom_text size 13 → 5 (mm scale, visually larger on canvas) --- .../implementations/python/letsplot.py | 168 ++++++++++-------- 1 file changed, 96 insertions(+), 72 deletions(-) diff --git a/plots/scatter-connected-temporal/implementations/python/letsplot.py b/plots/scatter-connected-temporal/implementations/python/letsplot.py index 423881f450..56562cd6bd 100644 --- a/plots/scatter-connected-temporal/implementations/python/letsplot.py +++ b/plots/scatter-connected-temporal/implementations/python/letsplot.py @@ -1,23 +1,58 @@ -""" pyplots.ai +"""anyplot.ai scatter-connected-temporal: Connected Scatter Plot with Temporal Path -Library: letsplot 4.9.0 | Python 3.14.3 -Quality: 90/100 | Created: 2026-03-13 +Library: letsplot | Python 3.13 +Quality: pending | Created: 2026-06-09 """ +import os + import numpy as np import pandas as pd -from lets_plot import * # noqa: F403 -from lets_plot.export import ggsave as export_ggsave +from lets_plot import ( + LetsPlot, + aes, + arrow, + element_blank, + element_line, + element_rect, + element_text, + geom_path, + geom_point, + geom_segment, + geom_text, + ggplot, + ggsave, + ggsize, + labs, + layer_tooltips, + scale_color_gradient, + scale_fill_gradient, + scale_x_continuous, + scale_y_continuous, + theme, + theme_minimal, +) + +LetsPlot.setup_html() -LetsPlot.setup_html() # noqa: F405 +# Theme tokens — Imprint palette, theme-adaptive chrome +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" +GRID = "rgba(26,26,23,0.12)" if THEME == "light" else "rgba(240,239,232,0.12)" -# Data — Unemployment rate vs inflation rate (Phillips curve), 1990-2023 +# Imprint sequential colormap: brand green (early) → blue (recent) +SEQ_LOW = "#009E73" # Imprint position 1 — start of temporal path +SEQ_HIGH = "#4467A3" # Imprint position 3 — end of temporal path + +# Data — Phillips curve dynamics, unemployment vs inflation 1990–2023 np.random.seed(42) years = np.arange(1990, 2024) n = len(years) -# Simulate realistic Phillips curve dynamics with regime shifts unemployment = np.concatenate( [ np.linspace(5.6, 4.0, 10) + np.random.randn(10) * 0.3, # 1990s decline @@ -47,14 +82,10 @@ } ) -# Color gradient: map time index to a normalized value for color encoding -df["time_norm"] = df["time_idx"] / (n - 1) - -# Label only key years — reduced set to avoid crowding in dense areas +# Annotate key economic turning points key_years = {1990, 2000, 2007, 2009, 2020, 2023} df_labels = df[df["year"].isin(key_years)].copy() -# Per-label offset to prevent overlap and clipping nudge_map = { 1990: (0.35, 0.7), 2000: (0.35, -0.7), @@ -64,96 +95,89 @@ 2023: (0.35, 0.7), } -# Highlight start and end points with larger markers df_endpoints = df[df["year"].isin([1990, 2023])].copy() df_labels["label_x"] = df_labels.apply(lambda r: r["unemployment"] + nudge_map.get(r["year"], (0, 0))[0], axis=1) df_labels["label_y"] = df_labels.apply(lambda r: r["inflation"] + nudge_map.get(r["year"], (0, 0))[1], axis=1) -# Arrow segment at end of path to show time direction +# Direction arrow at terminal segment of the path last = df.iloc[-1] prev = df.iloc[-2] - arrow_df = pd.DataFrame( {"x": [prev["unemployment"]], "y": [prev["inflation"]], "xend": [last["unemployment"]], "yend": [last["inflation"]]} ) +title = "scatter-connected-temporal · python · letsplot · anyplot.ai" + # Plot plot = ( - ggplot(df, aes(x="unemployment", y="inflation")) # noqa: F405 - + geom_path( # noqa: F405 - aes(color="time_idx"), # noqa: F405 - size=1.8, - alpha=0.7, - tooltips="none", - ) - + geom_segment( # noqa: F405 + ggplot(df, aes(x="unemployment", y="inflation")) + + geom_path(aes(color="time_idx"), size=1.5, alpha=0.75, tooltips="none") + + geom_segment( data=arrow_df, - mapping=aes(x="x", y="y", xend="xend", yend="yend"), # noqa: F405 - color="#1a3a5c", - size=2.5, - arrow=arrow(angle=25, length=12, type="closed"), # noqa: F405 + mapping=aes(x="x", y="y", xend="xend", yend="yend"), + color=SEQ_HIGH, + size=2.2, + arrow=arrow(angle=25, length=10, type="closed"), ) - + geom_point( # noqa: F405 - aes(fill="time_idx"), # noqa: F405 - color="white", - size=7, - stroke=1.2, + + geom_point( + aes(fill="time_idx"), + color=PAGE_BG, + size=3.5, + stroke=1.0, shape=21, - alpha=0.85, - tooltips=layer_tooltips() # noqa: F405 + alpha=0.9, + tooltips=layer_tooltips() .line("Year|@year") .line("Unemployment|@{unemployment}{.1f}%") .line("Inflation|@{inflation}{.1f}%"), ) - + geom_point( # noqa: F405 + + geom_point( data=df_endpoints, - mapping=aes(x="unemployment", y="inflation", fill="time_idx"), # noqa: F405 - color="#1a1a1a", - size=11, - stroke=2.0, + mapping=aes(x="unemployment", y="inflation", fill="time_idx"), + color=INK, + size=6.0, + stroke=1.8, shape=21, alpha=1.0, ) - + geom_text( # noqa: F405 + + geom_text( data=df_labels, - mapping=aes(x="label_x", y="label_y", label="year_label"), # noqa: F405 - size=13, - color="#222222", + mapping=aes(x="label_x", y="label_y", label="year_label"), + size=5, + color=INK, family="monospace", fontface="bold", ) - + scale_color_gradient( # noqa: F405 - low="#a8d5e2", high="#1a3a5c", name="Year", breaks=[0, (n - 1) / 2, n - 1], labels=["1990", "2006", "2023"] + + scale_color_gradient( + low=SEQ_LOW, high=SEQ_HIGH, name="Year", breaks=[0, (n - 1) / 2, n - 1], labels=["1990", "2006", "2023"] ) - + scale_fill_gradient( # noqa: F405 - low="#a8d5e2", high="#1a3a5c", guide="none" - ) - + scale_x_continuous(expand=[0.06, 0]) # noqa: F405 - + scale_y_continuous(expand=[0.08, 0]) # noqa: F405 - + labs( # noqa: F405 + + scale_fill_gradient(low=SEQ_LOW, high=SEQ_HIGH, guide="none") + + scale_x_continuous(expand=[0.06, 0]) + + scale_y_continuous(expand=[0.08, 0]) + + labs( x="Unemployment Rate (%)", y="Inflation Rate (%)", - title="scatter-connected-temporal · letsplot · pyplots.ai", - subtitle="Phillips Curve Dynamics — US-style unemployment vs inflation, 1990-2023", + title=title, + subtitle="Phillips Curve: unemployment vs inflation, 1990–2023", ) - + ggsize(1600, 900) # noqa: F405 - + theme_minimal() # noqa: F405 - + theme( # noqa: F405 - axis_text=element_text(size=16, color="#555555"), # noqa: F405 - axis_title=element_text(size=20, color="#333333"), # noqa: F405 - plot_title=element_text(size=24, color="#1a1a1a", face="bold"), # noqa: F405 - plot_subtitle=element_text(size=16, color="#555555"), # noqa: F405 - legend_text=element_text(size=14), # noqa: F405 - legend_title=element_text(size=16, face="bold"), # noqa: F405 - panel_grid_major=element_line(color="#E0E0E0", size=0.3), # noqa: F405 - panel_grid_minor=element_blank(), # noqa: F405 - plot_background=element_rect(fill="#FAFBFC"), # noqa: F405 - plot_margin=[60, 50, 20, 20], + + ggsize(800, 450) + + theme_minimal() + + theme( + axis_text=element_text(size=10, color=INK_SOFT), + axis_title=element_text(size=12, color=INK), + plot_title=element_text(size=16, color=INK), + plot_subtitle=element_text(size=10, color=INK_SOFT), + legend_text=element_text(size=10, color=INK_SOFT), + legend_title=element_text(size=12, color=INK), + panel_grid_major=element_line(color=GRID, size=0.3), + panel_grid_minor=element_blank(), + plot_background=element_rect(fill=PAGE_BG, color=PAGE_BG), + panel_background=element_rect(fill=PAGE_BG), + legend_background=element_rect(fill=ELEVATED_BG, color=INK_SOFT), + plot_margin=[20, 20, 10, 10], ) ) -# Save PNG (scale 3x to get 4800 x 2700 px) -export_ggsave(plot, filename="plot.png", path=".", scale=3) - -# Save HTML for interactive version -export_ggsave(plot, filename="plot.html", path=".") +# Save — PNG at 3200×1800 (800×450 × scale=4), plus interactive HTML +ggsave(plot, f"plot-{THEME}.png", path=".", scale=4) +ggsave(plot, f"plot-{THEME}.html", path=".") From ec1ad84e47a2f994eb6167676bbe2b1f58141944 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 9 Jun 2026 23:28:29 +0000 Subject: [PATCH 2/5] chore(letsplot): add metadata for scatter-connected-temporal --- .../metadata/python/letsplot.yaml | 240 ++---------------- 1 file changed, 16 insertions(+), 224 deletions(-) diff --git a/plots/scatter-connected-temporal/metadata/python/letsplot.yaml b/plots/scatter-connected-temporal/metadata/python/letsplot.yaml index db329f531b..9f7cb40da5 100644 --- a/plots/scatter-connected-temporal/metadata/python/letsplot.yaml +++ b/plots/scatter-connected-temporal/metadata/python/letsplot.yaml @@ -1,229 +1,21 @@ +# Per-library metadata for letsplot implementation of scatter-connected-temporal +# Auto-generated by impl-generate.yml + library: letsplot +language: python specification_id: scatter-connected-temporal created: '2026-03-13T15:24:50Z' -updated: '2026-03-13T15:45:39Z' -generated_by: claude-opus-4-5-20251101 -workflow_run: 23057666052 +updated: '2026-06-09T23:28:29Z' +generated_by: claude-sonnet +workflow_run: 27242210557 issue: 4675 -python_version: 3.14.3 -library_version: 4.9.0 -preview_url: https://storage.googleapis.com/anyplot-images/plots/scatter-connected-temporal/letsplot/plot.png -preview_html: https://storage.googleapis.com/anyplot-images/plots/scatter-connected-temporal/letsplot/plot.html -quality_score: 90 +language_version: 3.13.13 +library_version: 4.10.1 +preview_url_light: https://storage.googleapis.com/anyplot-images/plots/scatter-connected-temporal/python/letsplot/plot-light.png +preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/scatter-connected-temporal/python/letsplot/plot-dark.png +preview_html_light: https://storage.googleapis.com/anyplot-images/plots/scatter-connected-temporal/python/letsplot/plot-light.html +preview_html_dark: https://storage.googleapis.com/anyplot-images/plots/scatter-connected-temporal/python/letsplot/plot-dark.html +quality_score: null review: - strengths: - - Excellent data storytelling with regime-labeled key years and endpoint emphasis - creating a clear economic narrative - - Cohesive monochromatic blue gradient with professional visual hierarchy (point - sizing, arrow, borders) - - 'All spec features fully implemented: temporal color gradient, annotations, directional - arrow, visible markers' - - Realistic Phillips curve data with diverse regime shifts covering 34 years - - Clean idiomatic lets-plot code with interactive tooltips and HTML export - weaknesses: - - Mid-period points (light gray-blue) could have slightly more contrast against - the light background - - Annotation font size (13) is functional but on the smaller side relative to other - text elements - image_description: The plot displays a connected scatter plot showing Phillips Curve - dynamics (unemployment rate vs inflation rate) from 1990 to 2023. Points are connected - by line segments in chronological order, with a continuous color gradient from - light blue (1990) to dark navy blue (2023). Six key years (1990, 2000, 2007, 2009, - 2020, 2023) are annotated with bold monospace labels, each manually nudged to - avoid overlap. The start (1990) and end (2023) points are emphasized with larger - markers and darker borders. A directional arrow is drawn at the terminal segment - pointing toward the 2023 endpoint. The background is off-white (#FAFBFC) with - subtle light gray major grid lines and no minor grid. Axes are labeled "Unemployment - Rate (%)" and "Inflation Rate (%)" with a subtitle explaining the context. A vertical - color bar legend on the right maps the gradient to years 1990, 2006, 2023. - criteria_checklist: - visual_quality: - score: 28 - max: 30 - items: - - id: VQ-01 - name: Text Legibility - score: 7 - max: 8 - passed: true - comment: All font sizes explicitly set (title 24, axis title 20, axis text - 16, legend 14-16). Annotation labels at size 13 monospace bold readable - but slightly small. - - id: VQ-02 - name: No Overlap - score: 6 - max: 6 - passed: true - comment: Manual nudge offsets per label prevent all text collisions. - - id: VQ-03 - name: Element Visibility - score: 5 - max: 6 - passed: true - comment: Points clearly visible with white stroke borders. Mid-period light - gray-blue points blend slightly with grid. - - id: VQ-04 - name: Color Accessibility - score: 4 - max: 4 - passed: true - comment: Single-hue sequential blue gradient is fully colorblind-safe. - - id: VQ-05 - name: Layout & Canvas - score: 4 - max: 4 - passed: true - comment: Plot fills well over 50% of canvas with balanced margins. - - id: VQ-06 - name: Axis Labels & Title - score: 2 - max: 2 - passed: true - comment: 'Descriptive labels with units: Unemployment Rate (%), Inflation - Rate (%).' - design_excellence: - score: 15 - max: 20 - items: - - id: DE-01 - name: Aesthetic Sophistication - score: 6 - max: 8 - passed: true - comment: Cohesive monochromatic blue palette, white-bordered points, intentional - size hierarchy, directional arrow, off-white background. - - id: DE-02 - name: Visual Refinement - score: 4 - max: 6 - passed: true - comment: theme_minimal removes spines, minor grid suppressed, major grid subtle, - generous whitespace. - - id: DE-03 - name: Data Storytelling - score: 5 - max: 6 - passed: true - comment: Strong narrative through regime-labeled key years, emphasized endpoints, - and temporal arrow. - spec_compliance: - score: 15 - max: 15 - items: - - id: SC-01 - name: Plot Type - score: 5 - max: 5 - passed: true - comment: Connected scatter plot with temporal path, exactly as specified. - - id: SC-02 - name: Required Features - score: 4 - max: 4 - passed: true - comment: 'All features present: chronological connections, annotations, arrow, - markers, color gradient.' - - id: SC-03 - name: Data Mapping - score: 3 - max: 3 - passed: true - comment: X=unemployment, Y=inflation, temporal ordering correct. - - id: SC-04 - name: Title & Legend - score: 3 - max: 3 - passed: true - comment: Title format correct, legend labeled Year with correct breakpoints. - data_quality: - score: 15 - max: 15 - items: - - id: DQ-01 - name: Feature Coverage - score: 6 - max: 6 - passed: true - comment: 'Multiple regime shifts: 1990s decline, 2001 recession, mid-2000s - recovery, 2008 crisis, post-COVID spike.' - - id: DQ-02 - name: Realistic Context - score: 5 - max: 5 - passed: true - comment: US-style Phillips curve data with plausible economic dynamics. Neutral - topic. - - id: DQ-03 - name: Appropriate Scale - score: 4 - max: 4 - passed: true - comment: Unemployment 3-10%, inflation -1 to 8% — realistic US ranges. - code_quality: - score: 10 - max: 10 - items: - - id: CQ-01 - name: KISS Structure - score: 3 - max: 3 - passed: true - comment: Linear flow with no functions or classes. - - id: CQ-02 - name: Reproducibility - score: 2 - max: 2 - passed: true - comment: np.random.seed(42) set. - - id: CQ-03 - name: Clean Imports - score: 2 - max: 2 - passed: true - comment: All imports used. - - id: CQ-04 - name: Code Elegance - score: 2 - max: 2 - passed: true - comment: Clean and well-organized with practical nudge map approach. - - id: CQ-05 - name: Output & API - score: 1 - max: 1 - passed: true - comment: Saves as plot.png via export_ggsave with scale=3. - library_mastery: - score: 7 - max: 10 - items: - - id: LM-01 - name: Idiomatic Usage - score: 4 - max: 5 - passed: true - comment: Expert grammar-of-graphics composition with properly layered geoms - and paired scales. - - id: LM-02 - name: Distinctive Features - score: 3 - max: 5 - passed: true - comment: Uses layer_tooltips() with formatted hover info, arrow() in geom_segment, - and HTML export. - verdict: APPROVED -impl_tags: - dependencies: [] - techniques: - - annotations - - layer-composition - - hover-tooltips - - html-export - patterns: - - data-generation - dataprep: [] - styling: - - custom-colormap - - alpha-blending - - edge-highlighting - - grid-styling + strengths: [] + weaknesses: [] From 8d4b6257a72aba927bb006ce5a1b2b51e6d81e28 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 9 Jun 2026 23:33:46 +0000 Subject: [PATCH 3/5] chore(letsplot): update quality score 86 and review feedback for scatter-connected-temporal --- .../implementations/python/letsplot.py | 6 +- .../metadata/python/letsplot.yaml | 242 +++++++++++++++++- 2 files changed, 238 insertions(+), 10 deletions(-) diff --git a/plots/scatter-connected-temporal/implementations/python/letsplot.py b/plots/scatter-connected-temporal/implementations/python/letsplot.py index 56562cd6bd..3d8b151f60 100644 --- a/plots/scatter-connected-temporal/implementations/python/letsplot.py +++ b/plots/scatter-connected-temporal/implementations/python/letsplot.py @@ -1,7 +1,7 @@ -"""anyplot.ai +""" anyplot.ai scatter-connected-temporal: Connected Scatter Plot with Temporal Path -Library: letsplot | Python 3.13 -Quality: pending | Created: 2026-06-09 +Library: letsplot 4.10.1 | Python 3.13.13 +Quality: 86/100 | Updated: 2026-06-09 """ import os diff --git a/plots/scatter-connected-temporal/metadata/python/letsplot.yaml b/plots/scatter-connected-temporal/metadata/python/letsplot.yaml index 9f7cb40da5..4b7080a361 100644 --- a/plots/scatter-connected-temporal/metadata/python/letsplot.yaml +++ b/plots/scatter-connected-temporal/metadata/python/letsplot.yaml @@ -1,11 +1,8 @@ -# Per-library metadata for letsplot implementation of scatter-connected-temporal -# Auto-generated by impl-generate.yml - library: letsplot language: python specification_id: scatter-connected-temporal created: '2026-03-13T15:24:50Z' -updated: '2026-06-09T23:28:29Z' +updated: '2026-06-09T23:33:45Z' generated_by: claude-sonnet workflow_run: 27242210557 issue: 4675 @@ -15,7 +12,238 @@ preview_url_light: https://storage.googleapis.com/anyplot-images/plots/scatter-c preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/scatter-connected-temporal/python/letsplot/plot-dark.png preview_html_light: https://storage.googleapis.com/anyplot-images/plots/scatter-connected-temporal/python/letsplot/plot-light.html preview_html_dark: https://storage.googleapis.com/anyplot-images/plots/scatter-connected-temporal/python/letsplot/plot-dark.html -quality_score: null +quality_score: 86 review: - strengths: [] - weaknesses: [] + strengths: + - 'Full spec compliance: all required features (path, gradient, arrow, annotations, + endpoint highlights) implemented correctly.' + - Correct imprint_seq colormap (brand green to Imprint blue) with matching theme-adaptive + backgrounds in both renders. + - 'Excellent data storytelling: six annotated economic turning points with directional + arrow make the temporal narrative self-explanatory.' + - Code quality is exemplary — flat, reproducible, clean imports, elegant nudge_map + logic. + - layer_tooltips() with formatted year/unemployment/inflation fields is a genuine + letsplot strength well-exploited. + weaknesses: + - Panel box frame is present (rectangular border around data area) — style guide + default is L-shaped frame (remove top and right spines). Add theme(panel_border=element_blank()) + or equivalent. + - Year annotation font size=5mm is near the lower bound for mobile readability; + consider nudging to size=6 for the bold monospace labels. + - Path alpha=0.75 in the dense cluster (4-6% unemployment range) slightly reduces + segment clarity. + image_description: |- + Light render (plot-light.png): + Background: Warm off-white #FAF8F1 — correct Imprint light surface, not pure white. + Chrome: Title "scatter-connected-temporal · python · letsplot · anyplot.ai" visible in dark ink #1A1A17. Subtitle "Phillips Curve: unemployment vs inflation, 1990–2023" in soft ink. Axis labels "Unemployment Rate (%)" and "Inflation Rate (%)" both readable. Tick labels in INK_SOFT (#4A4A44). Year annotations (bold monospace) for 1990, 2000, 2007, 2009, 2020, 2023 all readable. Legend "Year" with colorbar labeled 1990/2006/2023. + Data: Temporal path from brand green #009E73 (1990) to Imprint blue #4467A3 (2023) — correct imprint_seq gradient. All 34 points visible as filled circles. 1990 and 2023 endpoints enlarged with dark ink rings. Directional arrow at terminal segment points toward 2023. + Legibility verdict: PASS — all text clearly readable against light background. + + Dark render (plot-dark.png): + Background: Warm near-black #1A1A17 — correct Imprint dark surface, not pure black. + Chrome: Title, subtitle, axis labels, tick labels, and year annotations all render in light cream (#F0EFE8 / #B8B7B0) and are clearly readable. No dark-on-dark failures detected. Grid lines subtle and visible. Legend text readable. + Data: Temporal gradient colors are identical to light render (brand green #009E73 to Imprint blue #4467A3) — only chrome tokens flip. 2023 endpoint marker has white ring (correct dark-theme INK). Brand green #009E73 clearly visible on dark background. + Legibility verdict: PASS — all text clearly readable against dark background. + criteria_checklist: + visual_quality: + score: 27 + max: 30 + items: + - id: VQ-01 + name: Text Legibility + score: 7 + max: 8 + passed: true + comment: All text readable in both themes; year annotation labels at geom_text + size=5mm are readable but approach lower bound for mobile readability. + - id: VQ-02 + name: No Overlap + score: 5 + max: 6 + passed: true + comment: Year labels nudged clear of data points. Dense path cluster makes + segments hard to distinguish but no text-on-text or text-on-data collisions. + - id: VQ-03 + name: Element Visibility + score: 5 + max: 6 + passed: true + comment: Temporal gradient clear, endpoint markers highlighted, direction + arrow prominent. Path alpha=0.75 slightly reduces clarity in dense mid-section. + - id: VQ-04 + name: Color Accessibility + score: 2 + max: 2 + passed: true + comment: imprint_seq (green to blue) is CVD-safe. + - id: VQ-05 + name: Layout & Canvas + score: 4 + max: 4 + passed: true + comment: Canvas gate passed (3200x1800). No overflow. Good proportions. + - id: VQ-06 + name: Axis Labels & Title + score: 2 + max: 2 + passed: true + comment: Descriptive labels with units; subtitle adds narrative context. + - id: VQ-07 + name: Palette Compliance + score: 2 + max: 2 + passed: true + comment: 'Correct imprint_seq gradient (SEQ_LOW=#009E73, SEQ_HIGH=#4467A3). + Backgrounds #FAF8F1/#1A1A17 correct. Both renders theme-correct.' + design_excellence: + score: 13 + max: 20 + items: + - id: DE-01 + name: Aesthetic Sophistication + score: 5 + max: 8 + passed: true + comment: 'Intentional visual hierarchy: dual point sizes, direction arrow, + bold monospace year labels. Subtitle adds Phillips Curve framing. Above + baseline.' + - id: DE-02 + name: Visual Refinement + score: 3 + max: 6 + passed: false + comment: theme_minimal() used but rectangular box panel frame remains visible. + Style guide default is L-shaped frame. Grid opacity well-controlled, minor + grid suppressed. + - id: DE-03 + name: Data Storytelling + score: 5 + max: 6 + passed: true + comment: Six key economic turning points annotated. Color gradient + direction + arrow encode time dimension. Clear focal point at 2023 spike. + spec_compliance: + score: 15 + max: 15 + items: + - id: SC-01 + name: Plot Type + score: 5 + max: 5 + passed: true + comment: Connected scatter with temporal path, exactly as specified. + - id: SC-02 + name: Required Features + score: 4 + max: 4 + passed: true + comment: Chronological path, color gradient, directional arrow, visible point + markers, year annotations all present. + - id: SC-03 + name: Data Mapping + score: 3 + max: 3 + passed: true + comment: X=unemployment, Y=inflation, time_idx as color aesthetic correctly + mapped. + - id: SC-04 + name: Title & Legend + score: 3 + max: 3 + passed: true + comment: Title is exactly scatter-connected-temporal · python · letsplot · + anyplot.ai. Year legend with 1990/2006/2023 labels. + data_quality: + score: 14 + max: 15 + items: + - id: DQ-01 + name: Feature Coverage + score: 5 + max: 6 + passed: true + comment: Scatter points, connecting path, color-encoded temporal progression, + directional arrow, key-event annotations — full feature set. + - id: DQ-02 + name: Realistic Context + score: 5 + max: 5 + passed: true + comment: Phillips Curve dynamics 1990–2023 with plausible recession/recovery + patterns. Neutral economic data. + - id: DQ-03 + name: Appropriate Scale + score: 4 + max: 4 + passed: true + comment: Unemployment 3–10%, inflation -1 to 8%, 34 annual points. Realistic + magnitudes. + code_quality: + score: 10 + max: 10 + items: + - id: CQ-01 + name: KISS Structure + score: 3 + max: 3 + passed: true + comment: Flat script, no functions or classes. + - id: CQ-02 + name: Reproducibility + score: 2 + max: 2 + passed: true + comment: np.random.seed(42). + - id: CQ-03 + name: Clean Imports + score: 2 + max: 2 + passed: true + comment: All imports used. + - id: CQ-04 + name: Code Elegance + score: 2 + max: 2 + passed: true + comment: nudge_map dict, key_years set, df_labels filtering — appropriate + complexity. + - id: CQ-05 + name: Output & API + score: 1 + max: 1 + passed: true + comment: Saves plot-{THEME}.png and plot-{THEME}.html. Current API. + library_mastery: + score: 7 + max: 10 + items: + - id: LM-01 + name: Idiomatic Usage + score: 4 + max: 5 + passed: true + comment: 'Full ggplot grammar: layered geoms, scale functions, theme(). shape=21 + idiomatic. ggsize + scale=4 correct for canvas.' + - id: LM-02 + name: Distinctive Features + score: 3 + max: 5 + passed: true + comment: layer_tooltips() with formatted field lines, HTML export, arrow() + in geom_segment. Could exploit more letsplot-specific capabilities. + verdict: APPROVED +impl_tags: + dependencies: [] + techniques: + - annotations + - hover-tooltips + - html-export + - layer-composition + patterns: + - data-generation + dataprep: [] + styling: + - alpha-blending + - custom-colormap + - edge-highlighting From 5a091b18819955e5575d9099f25c8062936f0737 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 9 Jun 2026 23:35:26 +0000 Subject: [PATCH 4/5] fix(letsplot): address review feedback for scatter-connected-temporal Attempt 1/3 - fixes based on AI review --- .../implementations/python/letsplot.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plots/scatter-connected-temporal/implementations/python/letsplot.py b/plots/scatter-connected-temporal/implementations/python/letsplot.py index 3d8b151f60..dc796f4751 100644 --- a/plots/scatter-connected-temporal/implementations/python/letsplot.py +++ b/plots/scatter-connected-temporal/implementations/python/letsplot.py @@ -1,4 +1,4 @@ -""" anyplot.ai +"""anyplot.ai scatter-connected-temporal: Connected Scatter Plot with Temporal Path Library: letsplot 4.10.1 | Python 3.13.13 Quality: 86/100 | Updated: 2026-06-09 @@ -143,7 +143,7 @@ + geom_text( data=df_labels, mapping=aes(x="label_x", y="label_y", label="year_label"), - size=5, + size=6, color=INK, family="monospace", fontface="bold", @@ -174,6 +174,7 @@ plot_background=element_rect(fill=PAGE_BG, color=PAGE_BG), panel_background=element_rect(fill=PAGE_BG), legend_background=element_rect(fill=ELEVATED_BG, color=INK_SOFT), + panel_border=element_blank(), plot_margin=[20, 20, 10, 10], ) ) From 1906640d67aa5b9e8de373d13fb161d251b7b141 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 9 Jun 2026 23:41:45 +0000 Subject: [PATCH 5/5] chore(letsplot): update quality score 88 and review feedback for scatter-connected-temporal --- .../implementations/python/letsplot.py | 4 +- .../metadata/python/letsplot.yaml | 166 +++++++++--------- 2 files changed, 89 insertions(+), 81 deletions(-) diff --git a/plots/scatter-connected-temporal/implementations/python/letsplot.py b/plots/scatter-connected-temporal/implementations/python/letsplot.py index dc796f4751..99a0860045 100644 --- a/plots/scatter-connected-temporal/implementations/python/letsplot.py +++ b/plots/scatter-connected-temporal/implementations/python/letsplot.py @@ -1,7 +1,7 @@ -"""anyplot.ai +""" anyplot.ai scatter-connected-temporal: Connected Scatter Plot with Temporal Path Library: letsplot 4.10.1 | Python 3.13.13 -Quality: 86/100 | Updated: 2026-06-09 +Quality: 88/100 | Updated: 2026-06-09 """ import os diff --git a/plots/scatter-connected-temporal/metadata/python/letsplot.yaml b/plots/scatter-connected-temporal/metadata/python/letsplot.yaml index 4b7080a361..f7bbf67305 100644 --- a/plots/scatter-connected-temporal/metadata/python/letsplot.yaml +++ b/plots/scatter-connected-temporal/metadata/python/letsplot.yaml @@ -2,7 +2,7 @@ library: letsplot language: python specification_id: scatter-connected-temporal created: '2026-03-13T15:24:50Z' -updated: '2026-06-09T23:33:45Z' +updated: '2026-06-09T23:41:45Z' generated_by: claude-sonnet workflow_run: 27242210557 issue: 4675 @@ -12,42 +12,45 @@ preview_url_light: https://storage.googleapis.com/anyplot-images/plots/scatter-c preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/scatter-connected-temporal/python/letsplot/plot-dark.png preview_html_light: https://storage.googleapis.com/anyplot-images/plots/scatter-connected-temporal/python/letsplot/plot-light.html preview_html_dark: https://storage.googleapis.com/anyplot-images/plots/scatter-connected-temporal/python/letsplot/plot-dark.html -quality_score: 86 +quality_score: 88 review: strengths: - - 'Full spec compliance: all required features (path, gradient, arrow, annotations, - endpoint highlights) implemented correctly.' - - Correct imprint_seq colormap (brand green to Imprint blue) with matching theme-adaptive - backgrounds in both renders. - - 'Excellent data storytelling: six annotated economic turning points with directional - arrow make the temporal narrative self-explanatory.' - - Code quality is exemplary — flat, reproducible, clean imports, elegant nudge_map - logic. - - layer_tooltips() with formatted year/unemployment/inflation fields is a genuine - letsplot strength well-exploited. + - Full spec compliance — temporal path, directional arrow, color gradient, endpoint + highlighting, and key-year annotations all implemented as required + - 'Correct Imprint sequential gradient (#009E73 → #4467A3) used for continuous temporal + encoding, matching imprint_seq exactly' + - Complete theme adaptation with correct token values (PAGE_BG, INK, INK_SOFT, ELEVATED_BG) + applied to all chrome elements — both renders are fully legible + - letsplot-native interactive tooltips via layer_tooltips() with formatted year/unemployment/inflation + data + - 'Compelling data storytelling: Phillips curve economic context, economic turning-point + annotations, temporal arrow — the narrative reads naturally' + - Canvas correctly 800×450 @ scale=4 → 3200×1800; HTML export also included weaknesses: - - Panel box frame is present (rectangular border around data area) — style guide - default is L-shaped frame (remove top and right spines). Add theme(panel_border=element_blank()) - or equivalent. - - Year annotation font size=5mm is near the lower bound for mobile readability; - consider nudging to size=6 for the bold monospace labels. - - Path alpha=0.75 in the dense cluster (4-6% unemployment range) slightly reduces - segment clarity. + - Year annotation text (geom_text size=6 mm ≈ 17pt at source resolution) is slightly + large relative to tick labels (10pt); reducing to size=4–5 mm would improve proportional + balance between annotation and tick label sizes + - Dense mid-plot cluster (unemployment 4–6%, 1990s–2000s regime) makes the temporal + path hard to follow locally — fading or thinning earlier path segments (e.g., + alpha ramping with time_idx) would improve readability of the historical path + - 'DE-01 headroom: standard horizontal gradient colorbar legend; a custom legend + approach (e.g., inline year markers at 1990/2006/2023 along the gradient bar with + small point icons) would lift aesthetic sophistication' image_description: |- Light render (plot-light.png): - Background: Warm off-white #FAF8F1 — correct Imprint light surface, not pure white. - Chrome: Title "scatter-connected-temporal · python · letsplot · anyplot.ai" visible in dark ink #1A1A17. Subtitle "Phillips Curve: unemployment vs inflation, 1990–2023" in soft ink. Axis labels "Unemployment Rate (%)" and "Inflation Rate (%)" both readable. Tick labels in INK_SOFT (#4A4A44). Year annotations (bold monospace) for 1990, 2000, 2007, 2009, 2020, 2023 all readable. Legend "Year" with colorbar labeled 1990/2006/2023. - Data: Temporal path from brand green #009E73 (1990) to Imprint blue #4467A3 (2023) — correct imprint_seq gradient. All 34 points visible as filled circles. 1990 and 2023 endpoints enlarged with dark ink rings. Directional arrow at terminal segment points toward 2023. - Legibility verdict: PASS — all text clearly readable against light background. + Background: Warm off-white (#FAF8F1) — correct, no pure white. + Chrome: Title "scatter-connected-temporal · python · letsplot · anyplot.ai" in dark ink at top-left — clearly readable. Subtitle "Phillips Curve: unemployment vs inflation, 1990–2023" in smaller INK_SOFT — readable. X-axis label "Unemployment Rate (%)" and Y-axis label "Inflation Rate (%)" in dark ink — both readable. Tick labels (3–10% on x, −1–8% on y) in INK_SOFT — all readable. Year annotations 1990/2000/2007/2009/2020/2023 in bold monospace dark ink — readable. Legend "Year" with 1990/2006/2023 labels on elevated (#FFFDF6) background — readable. + Data: Gradient path from green (#009E73, 1990) to blue (#4467A3, 2023). Small circular point markers along the path; larger endpoint markers (size=6) with INK border highlighting 1990 (green) and 2023 (blue). Arrow at terminal segment pointing toward 2023 in blue. Subtle grid visible behind data. + Legibility verdict: PASS — all text is clearly readable against the warm off-white background. No light-on-light issues. Dark render (plot-dark.png): - Background: Warm near-black #1A1A17 — correct Imprint dark surface, not pure black. - Chrome: Title, subtitle, axis labels, tick labels, and year annotations all render in light cream (#F0EFE8 / #B8B7B0) and are clearly readable. No dark-on-dark failures detected. Grid lines subtle and visible. Legend text readable. - Data: Temporal gradient colors are identical to light render (brand green #009E73 to Imprint blue #4467A3) — only chrome tokens flip. 2023 endpoint marker has white ring (correct dark-theme INK). Brand green #009E73 clearly visible on dark background. - Legibility verdict: PASS — all text clearly readable against dark background. + Background: Warm near-black (#1A1A17) — correct, no pure black. + Chrome: Title, subtitle, axis labels, tick labels, year annotations all rendered in light (#F0EFE8 / #B8B7B0) — clearly readable against the dark surface. Legend text light on elevated dark (#242420) background — readable. No dark-on-dark failures observed. + Data: Data colors (green-to-blue gradient) are identical to the light render — only chrome elements (text, background, grid, legend box) have flipped. Arrow and endpoint highlights use the same gradient values. + Legibility verdict: PASS — all text is clearly readable against the warm near-black background. No dark-on-dark issues. criteria_checklist: visual_quality: - score: 27 + score: 28 max: 30 items: - id: VQ-01 @@ -55,47 +58,50 @@ review: score: 7 max: 8 passed: true - comment: All text readable in both themes; year annotation labels at geom_text - size=5mm are readable but approach lower bound for mobile readability. + comment: All text readable in both renders. Year annotations (geom_text size=6mm + ~17pt) are slightly large relative to tick labels but not problematic. - id: VQ-02 name: No Overlap score: 5 max: 6 passed: true - comment: Year labels nudged clear of data points. Dense path cluster makes - segments hard to distinguish but no text-on-text or text-on-data collisions. + comment: nudge_map prevents point-label collision; minor visual crowding in + dense 4–6% unemployment cluster but no text overlap. - id: VQ-03 name: Element Visibility - score: 5 + score: 6 max: 6 passed: true - comment: Temporal gradient clear, endpoint markers highlighted, direction - arrow prominent. Path alpha=0.75 slightly reduces clarity in dense mid-section. + comment: Path (size=1.5, alpha=0.75), points (size=3.5), endpoint highlights + (size=6), arrow all clearly visible against background in both renders. - id: VQ-04 name: Color Accessibility score: 2 max: 2 passed: true - comment: imprint_seq (green to blue) is CVD-safe. + comment: Imprint sequential gradient (green→blue) is CVD-safe. Good contrast + in both themes. - id: VQ-05 name: Layout & Canvas score: 4 max: 4 passed: true - comment: Canvas gate passed (3200x1800). No overflow. Good proportions. + comment: Canvas gate passed (3200×1800). Good proportions, legend fits within + bounds, no clipping or overflow. - id: VQ-06 name: Axis Labels & Title score: 2 max: 2 passed: true - comment: Descriptive labels with units; subtitle adds narrative context. + comment: Both axis labels include units (%). Title format correct. Subtitle + provides context. - id: VQ-07 name: Palette Compliance score: 2 max: 2 passed: true - comment: 'Correct imprint_seq gradient (SEQ_LOW=#009E73, SEQ_HIGH=#4467A3). - Backgrounds #FAF8F1/#1A1A17 correct. Both renders theme-correct.' + comment: 'imprint_seq gradient (#009E73 → #4467A3). Backgrounds #FAF8F1/#1A1A17 + correct. Data colors identical across both renders; only chrome flips.' design_excellence: score: 13 max: 20 @@ -105,24 +111,25 @@ review: score: 5 max: 8 passed: true - comment: 'Intentional visual hierarchy: dual point sizes, direction arrow, - bold monospace year labels. Subtitle adds Phillips Curve framing. Above - baseline.' + comment: 'Above default: temporal gradient encoding, endpoint emphasis, directional + arrow, monospace bold annotations, theme adaptation. Standard gradient colorbar + limits ceiling.' - id: DE-02 name: Visual Refinement - score: 3 + score: 4 max: 6 - passed: false - comment: theme_minimal() used but rectangular box panel frame remains visible. - Style guide default is L-shaped frame. Grid opacity well-controlled, minor - grid suppressed. + passed: true + comment: 'Above default: panel_border removed, minor grid hidden, subtle grid + opacity (rgba 0.12), generous margins. Theme-minimal base with deliberate + overrides.' - id: DE-03 name: Data Storytelling - score: 5 + score: 4 max: 6 passed: true - comment: Six key economic turning points annotated. Color gradient + direction - arrow encode time dimension. Clear focal point at 2023 spike. + comment: 'Above default: Phillips curve narrative is clear, arrow shows direction + of time, gradient reinforces temporal flow, turning-point annotations provide + economic context.' spec_compliance: score: 15 max: 15 @@ -132,53 +139,53 @@ review: score: 5 max: 5 passed: true - comment: Connected scatter with temporal path, exactly as specified. + comment: Correct connected scatter plot with temporal path. - id: SC-02 name: Required Features score: 4 max: 4 passed: true - comment: Chronological path, color gradient, directional arrow, visible point - markers, year annotations all present. + comment: Sequential connections, key-year annotations, directional arrow, + visible point markers, temporal gradient — all present. - id: SC-03 name: Data Mapping score: 3 max: 3 passed: true - comment: X=unemployment, Y=inflation, time_idx as color aesthetic correctly - mapped. + comment: X=unemployment, Y=inflation, time_idx drives color gradient and path + ordering. 34 data points (1990–2023) within spec range. - id: SC-04 name: Title & Legend score: 3 max: 3 passed: true - comment: Title is exactly scatter-connected-temporal · python · letsplot · - anyplot.ai. Year legend with 1990/2006/2023 labels. + comment: Title 'scatter-connected-temporal · python · letsplot · anyplot.ai' + is correct. Year gradient legend with 1990/2006/2023 labels present. data_quality: - score: 14 + score: 15 max: 15 items: - id: DQ-01 name: Feature Coverage - score: 5 + score: 6 max: 6 passed: true - comment: Scatter points, connecting path, color-encoded temporal progression, - directional arrow, key-event annotations — full feature set. + comment: 'Full feature set: temporal path, color gradient, arrows, endpoint + highlights, interactive tooltips, key-year annotations.' - id: DQ-02 name: Realistic Context score: 5 max: 5 passed: true - comment: Phillips Curve dynamics 1990–2023 with plausible recession/recovery - patterns. Neutral economic data. + comment: Phillips curve is a well-established economic concept. Unemployment + 3.5–10% and inflation −0.4–6.5% are realistic. Economic turning points historically + grounded. Neutral, factual data. - id: DQ-03 name: Appropriate Scale score: 4 max: 4 passed: true - comment: Unemployment 3–10%, inflation -1 to 8%, 34 annual points. Realistic - magnitudes. + comment: 34 data points within spec's 10–100 range. Value ranges are domain-appropriate. code_quality: score: 10 max: 10 @@ -188,32 +195,32 @@ review: score: 3 max: 3 passed: true - comment: Flat script, no functions or classes. + comment: Flat script, no functions or classes, linear flow. - id: CQ-02 name: Reproducibility score: 2 max: 2 passed: true - comment: np.random.seed(42). + comment: np.random.seed(42) set. - id: CQ-03 name: Clean Imports score: 2 max: 2 passed: true - comment: All imports used. + comment: All lets_plot imports are used. os, numpy, pandas as expected. - id: CQ-04 name: Code Elegance score: 2 max: 2 passed: true - comment: nudge_map dict, key_years set, df_labels filtering — appropriate - complexity. + comment: Appropriate complexity. layer_tooltips() is real interactive feature, + not fake UI. - id: CQ-05 name: Output & API score: 1 max: 1 passed: true - comment: Saves plot-{THEME}.png and plot-{THEME}.html. Current API. + comment: Saves plot-{THEME}.png and plot-{THEME}.html. Current API usage. library_mastery: score: 7 max: 10 @@ -223,27 +230,28 @@ review: score: 4 max: 5 passed: true - comment: 'Full ggplot grammar: layered geoms, scale functions, theme(). shape=21 - idiomatic. ggsize + scale=4 correct for canvas.' + comment: 'Idiomatic ggplot grammar: geom layering, aes() mappings, scale_*_gradient, + theme_minimal() + theme() overrides, ggsize(), ggsave(scale=4).' - id: LM-02 name: Distinctive Features score: 3 max: 5 passed: true - comment: layer_tooltips() with formatted field lines, HTML export, arrow() - in geom_segment. Could exploit more letsplot-specific capabilities. + comment: Uses layer_tooltips() with custom line formatting (a distinctive + letsplot feature), arrow() function, geom_path() for connected ordering, + shape=21 fill/stroke split. Above default. verdict: APPROVED impl_tags: dependencies: [] techniques: - - annotations + - layer-composition - hover-tooltips - html-export - - layer-composition + - annotations patterns: - data-generation dataprep: [] styling: - - alpha-blending - custom-colormap + - alpha-blending - edge-highlighting