From ef080eaaea46f61e76a33c25a99262234a09df6d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 24 Jul 2026 18:09:43 +0000 Subject: [PATCH 1/7] feat(plotly): implement quiver-basic Regen from quality 80. Addressed: - arrow lines were hardcoded to legacy Python-Blue (#306998); now use Imprint BRAND (#009E73), always the first series color - continuous wind-speed color used non-compliant Viridis; now uses the Imprint sequential cmap (green -> blue) - code never read ANYPLOT_THEME and saved to plot.png/plot.html; now reads the env var, applies theme-adaptive chrome (title/axis/tick/grid colors, backgrounds), and saves plot-{theme}.png/.html - canvas was 4800x2700 (non-canonical); switched to the canonical square 2400x2400 format, which also fixes the wasted x-axis range (-4..4 for a +-2 data range) since a 1:1 aspect-locked radially symmetric vortex has no preferred horizontal axis - axis labels lacked units; added "(km)" and gave the plot a concrete scenario (cyclonic wind vortex, wind speed in m/s) - title fixed to the canonical "{descriptive} - {spec-id} - {language} - {library} - anyplot.ai" format with length-scaled fontsize - fixed a latent correctness bug: the true zero-magnitude vortex centre was overwritten to 1 before being used for marker color, misrepresenting the colorbar; now only the division-safe copy is patched Preserved strengths: ff.create_quiver + go.Scatter magnitude overlay, 15x15 grid density, scale_factor calibration, aspect-ratio lock for correct vector geometry. --- .../implementations/python/plotly.py | 90 ++++++++++++------- 1 file changed, 59 insertions(+), 31 deletions(-) diff --git a/plots/quiver-basic/implementations/python/plotly.py b/plots/quiver-basic/implementations/python/plotly.py index 7e757f6abd..bf0c1c3da2 100644 --- a/plots/quiver-basic/implementations/python/plotly.py +++ b/plots/quiver-basic/implementations/python/plotly.py @@ -1,41 +1,51 @@ -""" anyplot.ai +"""anyplot.ai quiver-basic: Basic Quiver Plot Library: plotly 6.7.0 | Python 3.13.13 -Quality: 80/100 | Updated: 2026-04-29 +Quality: 80/100 | Updated: 2026-07-24 """ +import os + import numpy as np import plotly.figure_factory as ff import plotly.graph_objects as go -# Data - create a 15x15 grid with circular rotation pattern (u = -y, v = x) +THEME = os.getenv("ANYPLOT_THEME", "light") +PAGE_BG = "#FAF8F1" if THEME == "light" else "#1A1A17" +INK = "#1A1A17" if THEME == "light" else "#F0EFE8" +INK_SOFT = "#4A4A44" if THEME == "light" else "#B8B7B0" +GRID = "rgba(26,26,23,0.15)" if THEME == "light" else "rgba(240,239,232,0.15)" + +# Imprint palette — brand green is always the first (and here, only) series color +BRAND = "#009E73" +# Continuous magnitude is single-polarity (0 -> max), so the sequential Imprint cmap applies +imprint_seq = [[0.0, "#009E73"], [1.0, "#4467A3"]] + +# Data - cyclonic wind vortex over a 4x4 km coastal grid (u = -y, v = x, m/s) np.random.seed(42) x_grid = np.linspace(-2, 2, 15) y_grid = np.linspace(-2, 2, 15) X, Y = np.meshgrid(x_grid, y_grid) -# Flatten for plotly x = X.flatten() y = Y.flatten() - -# Circular rotation pattern: u = -y, v = x u = -Y.flatten() v = X.flatten() -# Calculate magnitude for coloring +# True wind speed magnitude (0 at the eddy's calm centre, growing outward) magnitude = np.sqrt(u**2 + v**2) -magnitude[magnitude == 0] = 1 # Avoid division by zero at origin +safe_magnitude = np.where(magnitude == 0, 1e-6, magnitude) # Normalize vectors for consistent arrow length display scale_factor = 0.2 -u_norm = u / magnitude * scale_factor -v_norm = v / magnitude * scale_factor +u_norm = u / safe_magnitude * scale_factor +v_norm = v / safe_magnitude * scale_factor # Create quiver plot using figure_factory -fig = ff.create_quiver(x, y, u_norm, v_norm, scale=1, arrow_scale=0.3, line={"width": 2.5, "color": "#306998"}) +fig = ff.create_quiver(x, y, u_norm, v_norm, scale=1, arrow_scale=0.3, line={"width": 2.5, "color": BRAND}) -# Add scatter points at arrow bases for magnitude coloring +# Add scatter points at arrow bases for wind-speed coloring fig.add_trace( go.Scatter( x=x, @@ -44,46 +54,64 @@ marker={ "size": 10, "color": magnitude, - "colorscale": "Viridis", + "colorscale": imprint_seq, "colorbar": { - "title": {"text": "Magnitude", "font": {"size": 22}}, - "tickfont": {"size": 18}, + "title": {"text": "Wind Speed (m/s)", "font": {"size": 12, "color": INK}}, + "tickfont": {"size": 10, "color": INK_SOFT}, "thickness": 25, + "outlinewidth": 0, }, "showscale": True, }, - hovertemplate="x: %{x:.2f}
y: %{y:.2f}
magnitude: %{marker.color:.2f}", + hovertemplate="x: %{x:.2f} km
y: %{y:.2f} km
speed: %{marker.color:.2f} m/s", ) ) -# Layout for 4800x2700 px +# Title fontsize scales linearly with length off the 67-char / 16px baseline +title = "Cyclonic Wind Vortex · quiver-basic · python · plotly · anyplot.ai" +ratio = 67 / len(title) if len(title) > 67 else 1.0 +title_fontsize = max(11, round(16 * ratio)) + +# Layout for 2400x2400 px (Step 0 canonical square canvas — the vortex is +# radially symmetric with no preferred horizontal axis, and a square canvas +# avoids the wasted lateral space a 1:1 aspect-locked field would leave in a +# 16:9 frame) fig.update_layout( - title={"text": "Circular Flow Field · quiver-basic · plotly · pyplots.ai", "font": {"size": 32}, "x": 0.5}, + autosize=False, + width=600, + height=600, + title={"text": title, "font": {"size": title_fontsize, "color": INK}, "x": 0.5}, xaxis={ - "title": {"text": "X Position", "font": {"size": 24}}, - "tickfont": {"size": 18}, + "title": {"text": "X Position (km)", "font": {"size": 12, "color": INK}}, + "tickfont": {"size": 10, "color": INK_SOFT}, + "range": [-2.3, 2.3], "showgrid": True, - "gridcolor": "rgba(0,0,0,0.1)", + "gridcolor": GRID, "zeroline": True, - "zerolinecolor": "rgba(0,0,0,0.3)", + "zerolinecolor": INK_SOFT, + "linecolor": INK_SOFT, }, yaxis={ - "title": {"text": "Y Position", "font": {"size": 24}}, - "tickfont": {"size": 18}, + "title": {"text": "Y Position (km)", "font": {"size": 12, "color": INK}}, + "tickfont": {"size": 10, "color": INK_SOFT}, + "range": [-2.3, 2.3], "showgrid": True, - "gridcolor": "rgba(0,0,0,0.1)", + "gridcolor": GRID, "zeroline": True, - "zerolinecolor": "rgba(0,0,0,0.3)", + "zerolinecolor": INK_SOFT, + "linecolor": INK_SOFT, "scaleanchor": "x", "scaleratio": 1, }, - template="plotly_white", + paper_bgcolor=PAGE_BG, + plot_bgcolor=PAGE_BG, + font={"color": INK}, showlegend=False, - margin={"l": 80, "r": 130, "t": 100, "b": 80}, + margin={"l": 80, "r": 100, "t": 80, "b": 60}, ) -# Save as PNG (4800x2700 px) -fig.write_image("plot.png", width=1600, height=900, scale=3) +# Save as PNG (2400x2400 px) +fig.write_image(f"plot-{THEME}.png", width=600, height=600, scale=4) # Save as HTML for interactivity -fig.write_html("plot.html") +fig.write_html(f"plot-{THEME}.html", include_plotlyjs="cdn") From dd432f135a0be77d9877c261dfa8b79544816b01 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 24 Jul 2026 18:09:53 +0000 Subject: [PATCH 2/7] chore(plotly): add metadata for quiver-basic --- .../quiver-basic/metadata/python/plotly.yaml | 260 +----------------- 1 file changed, 10 insertions(+), 250 deletions(-) diff --git a/plots/quiver-basic/metadata/python/plotly.yaml b/plots/quiver-basic/metadata/python/plotly.yaml index a5e284aa37..d2547ea00b 100644 --- a/plots/quiver-basic/metadata/python/plotly.yaml +++ b/plots/quiver-basic/metadata/python/plotly.yaml @@ -1,261 +1,21 @@ +# Per-library metadata for plotly implementation of quiver-basic +# Auto-generated by impl-generate.yml + library: plotly language: python specification_id: quiver-basic created: '2025-12-23T18:12:55Z' -updated: '2026-04-29T22:49:10Z' +updated: '2026-07-24T18:09:53Z' generated_by: claude-sonnet -workflow_run: 25136941031 +workflow_run: 30115323638 issue: 1014 -python_version: 3.13.13 -library_version: 6.7.0 +language_version: 3.13.14 +library_version: 6.9.0 preview_url_light: https://storage.googleapis.com/anyplot-images/plots/quiver-basic/python/plotly/plot-light.png preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/quiver-basic/python/plotly/plot-dark.png preview_html_light: https://storage.googleapis.com/anyplot-images/plots/quiver-basic/python/plotly/plot-light.html preview_html_dark: https://storage.googleapis.com/anyplot-images/plots/quiver-basic/python/plotly/plot-dark.html -quality_score: 80 +quality_score: null review: - strengths: - - Uses plotly's ff.create_quiver — the purpose-built quiver utility — combined with - go.Scatter for magnitude color encoding, demonstrating solid library knowledge - - All font sizes explicitly set (title 32, axis 24, ticks 18, colorbar 22/18) — - fully readable in both renders - - Circular rotation field (u=-y, v=x) with viridis magnitude colorscale creates - an immediately readable vortex story - - Aspect-ratio lock (scaleanchor/scaleratio) preserves vector geometry — correct - for a quiver plot - - 'Arrow density (15×15 grid, scale_factor=0.2) is well-calibrated: no overlap, - each arrow distinguishable' - weaknesses: - - Arrow line color is hardcoded to '#306998' (legacy Python Blue) — explicitly non-compliant - per VQ-07; replace with BRAND = '#009E73' for the quiver lines or a neutral INK_SOFT - token - - Code does not read ANYPLOT_THEME env var and saves to 'plot.png'/'plot.html' instead - of 'plot-{THEME}.png'/'plot-{THEME}.html' — theme-adaptive chrome and correct - output filenames are missing from the source - - 'Axis labels lack units (''X Position'' / ''Y Position'' have no unit annotations); - title uses an extra description prefix instead of the canonical ''{spec-id} · - {library} · anyplot.ai'' format (current: ''Circular Flow Field · quiver-basic - · plotly · anyplot.ai'')' - - 'Design defaults dominate: template=''plotly_white'' with no spine removal, no - margin tuning beyond basic values, minimal customisation beyond font sizes — design - excellence remains at library-configured-default level' - image_description: |- - Light render (plot-light.png): - Background: Warm cream/off-white consistent with ~#FAF8F1 — not pure white. - Chrome: Title "Circular Flow Field · quiver-basic · plotly · anyplot.ai" in dark text, clearly readable. Axis labels "X Position" / "Y Position" readable. Tick labels readable at appropriate size. Colorbar label "Magnitude" with numeric ticks also readable. All chrome legible. - Data: 15×15 grid of quiver arrows showing a circular rotation pattern. Arrow lines appear in a consistent blue/teal hue (code specifies #306998). Scatter markers at arrow bases are coloured by the viridis scale — deep purple at centre (low magnitude ≈ 0) transitioning through green to bright yellow at the corners (high magnitude ≈ 2.83). Colorbar on the right encodes magnitude 0.5–2.5+. The vortex structure is immediately apparent. - Legibility verdict: PASS — all text readable, no light-on-light issues. - - Dark render (plot-dark.png): - Background: Near-black, consistent with ~#1A1A17 — not pure black. - Chrome: Title visible in white/light text against dark background. Axis labels and tick labels appear in light colour — readable. Colorbar "Magnitude" label and ticks visible. No dark-on-dark failures observed. - Data: Same viridis coloured markers and arrow pattern as light render — data colours are identical to the light render as required. The bright yellow outer arrows contrast well against the dark background. The deep purple centre arrows are slightly harder to see on dark but still distinguishable. - Legibility verdict: PASS — all text readable in light colours against dark background. Note: the dark theme chrome (light text, dark background) is present in the images but the committed source code does not include explicit ANYPLOT_THEME handling — the dark render may originate from a prior pipeline pass. The discrepancy is flagged as a code-level weakness. - criteria_checklist: - visual_quality: - score: 26 - max: 30 - items: - - id: VQ-01 - name: Text Legibility - score: 8 - max: 8 - passed: true - comment: 'All font sizes explicitly set: title 32, axis 24, ticks 18, colorbar - title 22, colorbar ticks 18. Readable in both themes.' - - id: VQ-02 - name: No Overlap - score: 6 - max: 6 - passed: true - comment: No overlapping elements. 15x15 grid well-spaced. - - id: VQ-03 - name: Element Visibility - score: 6 - max: 6 - passed: true - comment: Arrows clearly visible in both themes. scale_factor=0.2 well-calibrated. - Scatter markers size 10 provides good base visibility. - - id: VQ-04 - name: Color Accessibility - score: 2 - max: 2 - passed: true - comment: Viridis is CVD-safe perceptually uniform colorscale. - - id: VQ-05 - name: Layout & Canvas - score: 3 - max: 4 - passed: true - comment: Good proportions with aspect ratio lock. x-axis extends to ±4 for - a ±2 data range, leaving some wasted lateral space. - - id: VQ-06 - name: Axis Labels & Title - score: 1 - max: 2 - passed: false - comment: Axis labels 'X Position' / 'Y Position' are descriptive but lack - units. Title has extra description prefix. - - id: VQ-07 - name: Palette Compliance - score: 0 - max: 2 - passed: false - comment: Arrow lines hardcoded to '#306998' (legacy Python Blue) — explicitly - non-compliant. Viridis is correct for continuous magnitude data. Chrome - appears correct in images but ANYPLOT_THEME handling absent from code. - design_excellence: - score: 11 - max: 20 - items: - - id: DE-01 - name: Aesthetic Sophistication - score: 4 - max: 8 - passed: false - comment: Well-configured plotly_white template with intentional viridis colorscale. - Above pure defaults but not exceptional — no custom chrome colours, no spine - adjustments. - - id: DE-02 - name: Visual Refinement - score: 3 - max: 6 - passed: false - comment: Aspect ratio lock is a nice touch. Explicit font sizes add polish. - But template defaults dominate; no spine removal, no grid-opacity tuning. - - id: DE-03 - name: Data Storytelling - score: 4 - max: 6 - passed: true - comment: Circular vortex pattern tells an immediate story. Magnitude gradient - (dark centre → bright edges) creates natural visual hierarchy and guides - the viewer's eye outward. - spec_compliance: - score: 14 - max: 15 - items: - - id: SC-01 - name: Plot Type - score: 5 - max: 5 - passed: true - comment: Correct quiver plot using ff.create_quiver — the intended plotly - utility. - - id: SC-02 - name: Required Features - score: 4 - max: 4 - passed: true - comment: Uniform grid, arrows with direction encoding, magnitude encoded by - colour, mathematical rotation pattern u=-y v=x. All spec features present. - - id: SC-03 - name: Data Mapping - score: 3 - max: 3 - passed: true - comment: Correct x/y grid mapping. All data visible within axes. - - id: SC-04 - name: Title & Legend - score: 2 - max: 3 - passed: false - comment: Title contains spec-id, library, and anyplot.ai but adds a human-readable - description prefix 'Circular Flow Field ·', making it 4-part instead of - canonical 3-part format. No legend needed (colorbar serves as legend). - data_quality: - score: 13 - max: 15 - items: - - id: DQ-01 - name: Feature Coverage - score: 5 - max: 6 - passed: true - comment: Shows circular rotation with magnitude variation. Could show a second - field type (e.g. gradient vs rotation) for broader feature coverage. - - id: DQ-02 - name: Realistic Context - score: 4 - max: 5 - passed: true - comment: Circular vortex is a plausible real-world scenario (cyclone, fluid - vortex). Title could name the context more explicitly. - - id: DQ-03 - name: Appropriate Scale - score: 4 - max: 4 - passed: true - comment: Grid range ±2, magnitude 0–2.83 — appropriate and factually consistent - for the rotation formula. - code_quality: - score: 9 - max: 10 - items: - - id: CQ-01 - name: KISS Structure - score: 3 - max: 3 - passed: true - comment: Clean imports → data → plot → save structure. No functions or classes. - - id: CQ-02 - name: Reproducibility - score: 2 - max: 2 - passed: true - comment: np.random.seed(42) present. - - id: CQ-03 - name: Clean Imports - score: 2 - max: 2 - passed: true - comment: Only numpy, plotly.figure_factory, and plotly.graph_objects — all - used. - - id: CQ-04 - name: Code Elegance - score: 2 - max: 2 - passed: true - comment: Clean, readable, appropriate complexity. - - id: CQ-05 - name: Output & API - score: 0 - max: 1 - passed: false - comment: Saves as 'plot.png' and 'plot.html' instead of 'plot-{THEME}.png' - and 'plot-{THEME}.html'. No ANYPLOT_THEME env var read. Pipeline-level workaround - may exist but code does not comply with spec. - library_mastery: - score: 7 - max: 10 - items: - - id: LM-01 - name: Idiomatic Usage - score: 4 - max: 5 - passed: true - comment: ff.create_quiver is the idiomatic plotly approach. go.Scatter overlay - for colorbar is a correct pattern. Layout updates use plotly's dict API - correctly. - - id: LM-02 - name: Distinctive Features - score: 3 - max: 5 - passed: true - comment: ff.create_quiver is plotly figure_factory specific — not available - in most other libraries. Colorbar integration via marker colorscale is a - plotly strength. - verdict: APPROVED -impl_tags: - dependencies: [] - techniques: - - colorbar - - hover-tooltips - - html-export - patterns: - - data-generation - - matrix-construction - dataprep: - - normalization - styling: - - custom-colormap + strengths: [] + weaknesses: [] From 3c024ac700f5105a4bee8ae1702763c56983105e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 24 Jul 2026 18:14:48 +0000 Subject: [PATCH 3/7] chore(plotly): update quality score 82 and review feedback for quiver-basic --- .../implementations/python/plotly.py | 6 +- .../quiver-basic/metadata/python/plotly.yaml | 261 +++++++++++++++++- 2 files changed, 257 insertions(+), 10 deletions(-) diff --git a/plots/quiver-basic/implementations/python/plotly.py b/plots/quiver-basic/implementations/python/plotly.py index bf0c1c3da2..e54e648dcc 100644 --- a/plots/quiver-basic/implementations/python/plotly.py +++ b/plots/quiver-basic/implementations/python/plotly.py @@ -1,7 +1,7 @@ -"""anyplot.ai +""" anyplot.ai quiver-basic: Basic Quiver Plot -Library: plotly 6.7.0 | Python 3.13.13 -Quality: 80/100 | Updated: 2026-07-24 +Library: plotly 6.9.0 | Python 3.13.14 +Quality: 82/100 | Updated: 2026-07-24 """ import os diff --git a/plots/quiver-basic/metadata/python/plotly.yaml b/plots/quiver-basic/metadata/python/plotly.yaml index d2547ea00b..f7a89c423e 100644 --- a/plots/quiver-basic/metadata/python/plotly.yaml +++ b/plots/quiver-basic/metadata/python/plotly.yaml @@ -1,11 +1,8 @@ -# Per-library metadata for plotly implementation of quiver-basic -# Auto-generated by impl-generate.yml - library: plotly language: python specification_id: quiver-basic created: '2025-12-23T18:12:55Z' -updated: '2026-07-24T18:09:53Z' +updated: '2026-07-24T18:14:47Z' generated_by: claude-sonnet workflow_run: 30115323638 issue: 1014 @@ -15,7 +12,257 @@ preview_url_light: https://storage.googleapis.com/anyplot-images/plots/quiver-ba preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/quiver-basic/python/plotly/plot-dark.png preview_html_light: https://storage.googleapis.com/anyplot-images/plots/quiver-basic/python/plotly/plot-light.html preview_html_dark: https://storage.googleapis.com/anyplot-images/plots/quiver-basic/python/plotly/plot-dark.html -quality_score: null +quality_score: 82 review: - strengths: [] - weaknesses: [] + strengths: + - 'Correct plot type: ff.create_quiver renders a true quiver field with direction + correctly derived from u=-y, v=x (counterclockwise rotation), matching the described + cyclonic vortex.' + - 'Theme handling is fully correct in both renders: PAGE_BG, INK, INK_SOFT, and + GRID all branch on ANYPLOT_THEME and match the required #FAF8F1/#1A1A17 hex values + with no dark-on-dark or light-on-light failures.' + - 'Imprint palette compliance: arrows use brand green #009E73, and the magnitude + overlay correctly uses the sequential imprint_seq colormap (green -> blue) since + wind speed is single-polarity data, not the diverging scale.' + - 'Smart redundant encoding: layering a go.Scatter trace colored by magnitude on + top of the quiver arrows adds a colorbar-driven magnitude read that a plain create_quiver + call couldn''t provide on its own.' + - All font sizes are explicitly set (title, axis titles, tick labels, colorbar title/ticks) + and scale the title fontsize by length via a documented ratio formula, avoiding + overflow with the long mandated title. + - 'Clean, KISS-structured code: single top-to-bottom script, no functions/classes, + deterministic data generation, only necessary imports (numpy, plotly.figure_factory, + plotly.graph_objects, os).' + weaknesses: + - 'Spec violation: the spec explicitly requires arrow ''length proportional to its + magnitude,'' but the implementation normalizes every vector to the exact same + length (u_norm = u/magnitude*scale_factor with a fixed scale_factor=0.2). Every + arrow in both renders is visually the same length regardless of true wind speed, + so the primary quiver-plot encoding channel (length) carries no information -- + only direction and the separate scatter-marker color show magnitude. Repair should + scale arrow length by relative magnitude (e.g. u_norm = u * scale_factor / max_magnitude) + so the radial gradient in speed is visible in the arrows themselves, while still + keeping near-center arrows visible.' + - 'DQ-03: the wind-speed values are physically very low for a ''cyclonic wind vortex'' + -- magnitude ranges only 0-2.83 m/s (light-air/light-breeze range on the Beaufort + scale), not the tens of m/s associated with real cyclonic wind systems. Either + scale the underlying u/v field (or add a physically-motivated multiplier before + computing magnitude) so speeds fall in a plausible cyclone range (roughly 5-30 + m/s), or soften the ''cyclonic'' framing in the title/description to match a gentle + eddy.' + - 'DE-01/DE-02: styling is solid but still close to a well-configured default -- + the 225-arrow field plus scatter dots is a little visually busy at this density; + consider a lighter marker size or slightly more transparent arrows so the vortex + structure reads more clearly as a focal point rather than a uniform grid.' + - 'VQ-05: the right margin (r=100) reserved for the colorbar makes the plot area + sit slightly left-of-center within the square canvas; tightening the colorbar + thickness/margin would rebalance whitespace.' + image_description: |- + Light render (plot-light.png): + Background: Warm off-white, matches #FAF8F1 -- not pure white. + Chrome: Title "Cyclonic Wind Vortex · quiver-basic · python · plotly · anyplot.ai" is dark ink, centered, fully visible, no clipping or overflow past the canvas. X-axis title "X Position (km)" and Y-axis title "Y Position (km)" are dark ink and readable. Tick labels (-2, -1, 0, 1, 2 on both axes) are a softer dark gray, clearly legible. Colorbar title "Wind Speed (m/s)" and its tick labels (0, 0.5, 1, 1.5, 2, 2.5) are dark ink / soft gray respectively, both readable. Gridlines are faint, subtle, do not compete with data. A darker zero-line marks the x=0 and y=0 axes, which reads as a deliberate reference to the vortex core. + Data: A 15x15 grid of arrows forms a circular/rotational flow pattern consistent with u=-y, v=x (counterclockwise vortex). All arrows are brand green (#009E73) and rendered at a uniform length -- length does NOT vary with true vector magnitude (see weaknesses). Underlying scatter markers at each arrow base are colored via a green-to-blue sequential gradient (imprint_seq) keyed to wind speed magnitude, growing bluer toward the grid's outer edge and staying green near the calm center. + Legibility verdict: PASS -- every text element is clearly readable against the light background; no light-on-light issues. + + Dark render (plot-dark.png): + Background: Warm near-black, matches #1A1A17 -- not pure black. + Chrome: Title, axis titles, and colorbar title switch to light ink (#F0EFE8) and are clearly visible. Tick labels and colorbar ticks switch to the lighter soft-gray token (#B8B7B0) and remain legible. Gridlines and the zero-line are visible but subtle against the dark surface. No dark-on-dark text anywhere. + Data: Arrow color (#009E73) and the scatter marker green-to-blue gradient are pixel-identical to the light render -- only the chrome (background, text, grid) flipped, confirming palette consistency across themes. + Legibility verdict: PASS -- all text is clearly readable against the dark background; no dark-on-dark failures detected. + criteria_checklist: + visual_quality: + score: 27 + max: 30 + items: + - id: VQ-01 + name: Text Legibility + score: 7 + max: 8 + passed: true + comment: All font sizes explicitly set (title fontsize scaled to title length, + axis/tick/colorbar sizes fixed); readable in both themes with no overflow + or clipping. + - id: VQ-02 + name: No Overlap + score: 6 + max: 6 + passed: true + comment: No text overlaps other text, data, or the colorbar in either render. + - id: VQ-03 + name: Element Visibility + score: 5 + max: 6 + passed: true + comment: Arrows and 10px scatter markers are visible for a 225-arrow grid; + density is reasonable though the field reads slightly busy. + - id: VQ-04 + name: Color Accessibility + score: 2 + max: 2 + passed: true + comment: Imprint palette is CVD-safe; green-to-blue gradient plus arrow direction + gives redundant, non-red-green encoding. + - id: VQ-05 + name: Layout & Canvas + score: 3 + max: 4 + passed: true + comment: Plot fills a good share of the square canvas; extra right margin + for the colorbar leaves the plot slightly left-of-center. + - id: VQ-06 + name: Axis Labels & Title + score: 2 + max: 2 + passed: true + comment: Axis titles and colorbar title include units (km, m/s). + - id: VQ-07 + name: Palette Compliance + score: 2 + max: 2 + passed: true + comment: 'First/only categorical series is #009E73; continuous magnitude correctly + uses imprint_seq (single-polarity data); both renders theme-correct.' + design_excellence: + score: 13 + max: 20 + items: + - id: DE-01 + name: Aesthetic Sophistication + score: 5 + max: 8 + comment: Above a bare default -- custom palette and an intentional two-layer + composition -- but the dense uniform-length arrow grid limits polish. + - id: DE-02 + name: Visual Refinement + score: 4 + max: 6 + comment: Subtle grid, default L-shaped spines, reasonable whitespace; colorbar + margin slightly unbalances the layout. + - id: DE-03 + name: Data Storytelling + score: 4 + max: 6 + comment: Color gradient from calm green center to faster blue edge creates + a clear visual hierarchy and focal point at the vortex core. + spec_compliance: + score: 13 + max: 15 + items: + - id: SC-01 + name: Plot Type + score: 5 + max: 5 + passed: true + comment: Correct quiver plot via ff.create_quiver with accurate directional + field. + - id: SC-02 + name: Required Features + score: 2 + max: 4 + passed: false + comment: Spec requires arrow length proportional to magnitude; implementation + normalizes all arrows to a fixed length, so this required feature is not + represented in the arrows themselves (only via a separate color channel). + - id: SC-03 + name: Data Mapping + score: 3 + max: 3 + passed: true + comment: x/y correctly mapped to position, u/v correctly mapped to direction; + axes show the full -2..2 grid. + - id: SC-04 + name: Title & Legend + score: 3 + max: 3 + passed: true + comment: Title matches '{Descriptive Title} · spec-id · python · plotly · + anyplot.ai' format; colorbar serves as the legend and is correctly labeled. + data_quality: + score: 12 + max: 15 + items: + - id: DQ-01 + name: Feature Coverage + score: 4 + max: 6 + comment: Shows direction and relative magnitude via color, but the length-based + magnitude feature central to quiver plots is missing from the arrows. + - id: DQ-02 + name: Realistic Context + score: 5 + max: 5 + passed: true + comment: Meteorology / coastal wind vortex is a neutral, comprehensible, real-world + scenario. + - id: DQ-03 + name: Appropriate Scale + score: 3 + max: 4 + comment: Values are plausible as numbers but the 0-2.83 m/s range is too gentle + (light-air/breeze) to be physically representative of a 'cyclonic' wind + vortex. + code_quality: + score: 10 + max: 10 + items: + - id: CQ-01 + name: KISS Structure + score: 3 + max: 3 + passed: true + comment: Linear script, no functions/classes. + - id: CQ-02 + name: Reproducibility + score: 2 + max: 2 + passed: true + comment: np.random.seed(42) set; data generation is deterministic. + - id: CQ-03 + name: Clean Imports + score: 2 + max: 2 + passed: true + comment: Only os, numpy, plotly.figure_factory, plotly.graph_objects -- all + used. + - id: CQ-04 + name: Code Elegance + score: 2 + max: 2 + passed: true + comment: Clean, appropriately complex, no fake functionality. + - id: CQ-05 + name: Output & API + score: 1 + max: 1 + passed: true + comment: Saves plot-{THEME}.png and plot-{THEME}.html via current write_image/write_html + API. + library_mastery: + score: 7 + max: 10 + items: + - id: LM-01 + name: Idiomatic Usage + score: 4 + max: 5 + comment: Uses plotly's dedicated figure_factory quiver API plus a layered + go.Scatter trace, following the library's recommended high-level patterns. + - id: LM-02 + name: Distinctive Features + score: 3 + max: 5 + comment: Combining create_quiver with a colorbar-driven scatter overlay is + a plotly-specific composition technique beyond generic usage. + verdict: REJECTED +impl_tags: + dependencies: [] + techniques: + - colorbar + - layer-composition + patterns: + - data-generation + - matrix-construction + dataprep: + - normalization + styling: + - custom-colormap From e3d18ee5bf313f4c0bf7b3ab6e29f138fc851f8b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 24 Jul 2026 18:19:26 +0000 Subject: [PATCH 4/7] fix(plotly): address review feedback for quiver-basic Attempt 1/4 - fixes based on AI review --- .../implementations/python/plotly.py | 46 ++++++++++++------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/plots/quiver-basic/implementations/python/plotly.py b/plots/quiver-basic/implementations/python/plotly.py index e54e648dcc..bd13b020db 100644 --- a/plots/quiver-basic/implementations/python/plotly.py +++ b/plots/quiver-basic/implementations/python/plotly.py @@ -1,14 +1,20 @@ -""" anyplot.ai +"""anyplot.ai quiver-basic: Basic Quiver Plot Library: plotly 6.9.0 | Python 3.13.14 Quality: 82/100 | Updated: 2026-07-24 """ import os +import sys -import numpy as np -import plotly.figure_factory as ff -import plotly.graph_objects as go + +# Prevent this file from shadowing the installed plotly package +_this_dir = os.path.dirname(os.path.abspath(__file__)) +sys.path = [p for p in sys.path if os.path.abspath(p) != _this_dir] + +import numpy as np # noqa: E402 +import plotly.figure_factory as ff # noqa: E402 +import plotly.graph_objects as go # noqa: E402 THEME = os.getenv("ANYPLOT_THEME", "light") @@ -24,26 +30,32 @@ # Data - cyclonic wind vortex over a 4x4 km coastal grid (u = -y, v = x, m/s) np.random.seed(42) -x_grid = np.linspace(-2, 2, 15) -y_grid = np.linspace(-2, 2, 15) +x_grid = np.linspace(-2, 2, 13) +y_grid = np.linspace(-2, 2, 13) X, Y = np.meshgrid(x_grid, y_grid) x = X.flatten() y = Y.flatten() -u = -Y.flatten() -v = X.flatten() +# Cyclone-strength wind speeds (Beaufort ~5-30 m/s range) via a physical multiplier +WIND_SPEED_SCALE = 10.0 +u = -Y.flatten() * WIND_SPEED_SCALE +v = X.flatten() * WIND_SPEED_SCALE # True wind speed magnitude (0 at the eddy's calm centre, growing outward) magnitude = np.sqrt(u**2 + v**2) +max_magnitude = magnitude.max() safe_magnitude = np.where(magnitude == 0, 1e-6, magnitude) -# Normalize vectors for consistent arrow length display -scale_factor = 0.2 -u_norm = u / safe_magnitude * scale_factor -v_norm = v / safe_magnitude * scale_factor +# Arrow length scales with relative magnitude (proportional encoding), with a +# small floor so the calm-centre arrows stay visible instead of vanishing +scale_factor = 0.32 +min_length_frac = 0.18 +length_frac = min_length_frac + (1 - min_length_frac) * (magnitude / max_magnitude) +u_norm = (u / safe_magnitude) * length_frac * scale_factor +v_norm = (v / safe_magnitude) * length_frac * scale_factor # Create quiver plot using figure_factory -fig = ff.create_quiver(x, y, u_norm, v_norm, scale=1, arrow_scale=0.3, line={"width": 2.5, "color": BRAND}) +fig = ff.create_quiver(x, y, u_norm, v_norm, scale=1, arrow_scale=0.3, line={"width": 2, "color": BRAND}) # Add scatter points at arrow bases for wind-speed coloring fig.add_trace( @@ -52,14 +64,16 @@ y=y, mode="markers", marker={ - "size": 10, + "size": 6, + "opacity": 0.65, "color": magnitude, "colorscale": imprint_seq, "colorbar": { "title": {"text": "Wind Speed (m/s)", "font": {"size": 12, "color": INK}}, "tickfont": {"size": 10, "color": INK_SOFT}, - "thickness": 25, + "thickness": 16, "outlinewidth": 0, + "len": 0.8, }, "showscale": True, }, @@ -107,7 +121,7 @@ plot_bgcolor=PAGE_BG, font={"color": INK}, showlegend=False, - margin={"l": 80, "r": 100, "t": 80, "b": 60}, + margin={"l": 80, "r": 70, "t": 80, "b": 60}, ) # Save as PNG (2400x2400 px) From 91549a885222b4377ba47aa3ba1e78e8899d2b20 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 24 Jul 2026 18:28:03 +0000 Subject: [PATCH 5/7] chore(plotly): update quality score 76 and review feedback for quiver-basic --- .../implementations/python/plotly.py | 4 +- .../quiver-basic/metadata/python/plotly.yaml | 218 +++++++++--------- 2 files changed, 116 insertions(+), 106 deletions(-) diff --git a/plots/quiver-basic/implementations/python/plotly.py b/plots/quiver-basic/implementations/python/plotly.py index bd13b020db..d97babce7e 100644 --- a/plots/quiver-basic/implementations/python/plotly.py +++ b/plots/quiver-basic/implementations/python/plotly.py @@ -1,7 +1,7 @@ -"""anyplot.ai +""" anyplot.ai quiver-basic: Basic Quiver Plot Library: plotly 6.9.0 | Python 3.13.14 -Quality: 82/100 | Updated: 2026-07-24 +Quality: 76/100 | Updated: 2026-07-24 """ import os diff --git a/plots/quiver-basic/metadata/python/plotly.yaml b/plots/quiver-basic/metadata/python/plotly.yaml index f7a89c423e..82be9dd55b 100644 --- a/plots/quiver-basic/metadata/python/plotly.yaml +++ b/plots/quiver-basic/metadata/python/plotly.yaml @@ -2,7 +2,7 @@ library: plotly language: python specification_id: quiver-basic created: '2025-12-23T18:12:55Z' -updated: '2026-07-24T18:14:47Z' +updated: '2026-07-24T18:28:02Z' generated_by: claude-sonnet workflow_run: 30115323638 issue: 1014 @@ -12,66 +12,71 @@ preview_url_light: https://storage.googleapis.com/anyplot-images/plots/quiver-ba preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/quiver-basic/python/plotly/plot-dark.png preview_html_light: https://storage.googleapis.com/anyplot-images/plots/quiver-basic/python/plotly/plot-light.html preview_html_dark: https://storage.googleapis.com/anyplot-images/plots/quiver-basic/python/plotly/plot-dark.html -quality_score: 82 +quality_score: 76 review: strengths: - 'Correct plot type: ff.create_quiver renders a true quiver field with direction correctly derived from u=-y, v=x (counterclockwise rotation), matching the described cyclonic vortex.' - - 'Theme handling is fully correct in both renders: PAGE_BG, INK, INK_SOFT, and - GRID all branch on ANYPLOT_THEME and match the required #FAF8F1/#1A1A17 hex values - with no dark-on-dark or light-on-light failures.' + - 'Theme handling is fully correct in both provided renders: PAGE_BG, INK, INK_SOFT, + and GRID all branch on ANYPLOT_THEME and match the required #FAF8F1/#1A1A17 hex + values with no dark-on-dark or light-on-light failures.' - 'Imprint palette compliance: arrows use brand green #009E73, and the magnitude - overlay correctly uses the sequential imprint_seq colormap (green -> blue) since + overlay correctly uses the sequential imprint_seq colormap (green to blue) since wind speed is single-polarity data, not the diverging scale.' - - 'Smart redundant encoding: layering a go.Scatter trace colored by magnitude on - top of the quiver arrows adds a colorbar-driven magnitude read that a plain create_quiver - call couldn''t provide on its own.' - - All font sizes are explicitly set (title, axis titles, tick labels, colorbar title/ticks) - and scale the title fontsize by length via a documented ratio formula, avoiding - overflow with the long mandated title. + - 'Reading the current source directly (plots/quiver-basic/implementations/python/plotly.py + at HEAD) confirms the attempt-1 weaknesses were genuinely addressed in code: arrow + length now scales with relative magnitude via length_frac, and WIND_SPEED_SCALE=10.0 + pushes peak wind speed into a plausible cyclone range (~28 m/s). This is good, + correct engineering work by the repair step.' - 'Clean, KISS-structured code: single top-to-bottom script, no functions/classes, - deterministic data generation, only necessary imports (numpy, plotly.figure_factory, - plotly.graph_objects, os).' + deterministic data generation (np.random.seed(42)), only necessary imports.' weaknesses: - - 'Spec violation: the spec explicitly requires arrow ''length proportional to its - magnitude,'' but the implementation normalizes every vector to the exact same - length (u_norm = u/magnitude*scale_factor with a fixed scale_factor=0.2). Every - arrow in both renders is visually the same length regardless of true wind speed, - so the primary quiver-plot encoding channel (length) carries no information -- - only direction and the separate scatter-marker color show magnitude. Repair should - scale arrow length by relative magnitude (e.g. u_norm = u * scale_factor / max_magnitude) - so the radial gradient in speed is visible in the arrows themselves, while still - keeping near-center arrows visible.' - - 'DQ-03: the wind-speed values are physically very low for a ''cyclonic wind vortex'' - -- magnitude ranges only 0-2.83 m/s (light-air/light-breeze range on the Beaufort - scale), not the tens of m/s associated with real cyclonic wind systems. Either - scale the underlying u/v field (or add a physically-motivated multiplier before - computing magnitude) so speeds fall in a plausible cyclone range (roughly 5-30 - m/s), or soften the ''cyclonic'' framing in the title/description to match a gentle - eddy.' - - 'DE-01/DE-02: styling is solid but still close to a well-configured default -- - the 225-arrow field plus scatter dots is a little visually busy at this density; - consider a lighter marker size or slightly more transparent arrows so the vortex - structure reads more clearly as a focal point rather than a uniform grid.' - - 'VQ-05: the right margin (r=100) reserved for the colorbar makes the plot area - sit slightly left-of-center within the square canvas; tightening the colorbar - thickness/margin would rebalance whitespace.' + - 'CRITICAL - PIPELINE FAILURE, not a code defect: the plot-light.png / plot-dark.png + supplied for this review do not reflect the current commit (e3d18ee5b). Evidence: + (1) the colorbar in the provided renders tops out at ~2.8 m/s, but directly executing + the current plots/quiver-basic/implementations/python/plotly.py locally (ANYPLOT_THEME=light) + produces a colorbar spanning 0-28.3 m/s, matching WIND_SPEED_SCALE=10.0 in the + current source. (2) the provided renders show every arrow at a visually uniform + length, but executing the current source produces arrows whose length clearly + grows from the vortex centre outward, matching the length_frac formula in the + current source. (3) rendering the PRE-repair commit (dd432f135) locally reproduces + the provided plot-light.png pixel-for-pixel (same 0-2.8 m/s colorbar, same uniform + arrow lengths, same marker size/opacity). This proves the images attached to this + PR for review are the stale attempt-1 (pre-repair) render, not the output of the + fix that was actually committed. Do NOT make further code edits to fix arrow-length-proportionality + or wind-speed-realism -- both are already correctly implemented in the current + source. Instead the workflow must re-render plot-light.png/plot-dark.png from + the current HEAD commit before the next AI review, or this repair loop will keep + scoring against a stale artifact and can never converge.' + - 'As shown in the (stale) provided renders: every arrow is the same length regardless + of position, so the spec''s ''length proportional to magnitude'' requirement is + not visible in what was reviewed -- though this is understood to already be fixed + in the underlying source per the note above.' + - 'As shown in the (stale) provided renders: wind speed only reaches ~2.8 m/s (light-air + range), too gentle for a ''cyclonic'' vortex -- though this is understood to already + be fixed in the underlying source (peak ~28 m/s) per the note above.' + - Cannot fully evaluate Design Excellence / Library Mastery improvements for this + attempt since the visual artifact under review is unchanged from attempt 1 -- + re-review once fresh renders are available. image_description: |- Light render (plot-light.png): - Background: Warm off-white, matches #FAF8F1 -- not pure white. - Chrome: Title "Cyclonic Wind Vortex · quiver-basic · python · plotly · anyplot.ai" is dark ink, centered, fully visible, no clipping or overflow past the canvas. X-axis title "X Position (km)" and Y-axis title "Y Position (km)" are dark ink and readable. Tick labels (-2, -1, 0, 1, 2 on both axes) are a softer dark gray, clearly legible. Colorbar title "Wind Speed (m/s)" and its tick labels (0, 0.5, 1, 1.5, 2, 2.5) are dark ink / soft gray respectively, both readable. Gridlines are faint, subtle, do not compete with data. A darker zero-line marks the x=0 and y=0 axes, which reads as a deliberate reference to the vortex core. - Data: A 15x15 grid of arrows forms a circular/rotational flow pattern consistent with u=-y, v=x (counterclockwise vortex). All arrows are brand green (#009E73) and rendered at a uniform length -- length does NOT vary with true vector magnitude (see weaknesses). Underlying scatter markers at each arrow base are colored via a green-to-blue sequential gradient (imprint_seq) keyed to wind speed magnitude, growing bluer toward the grid's outer edge and staying green near the calm center. - Legibility verdict: PASS -- every text element is clearly readable against the light background; no light-on-light issues. + Background: Warm off-white, consistent with #FAF8F1. Correct, not pure white. + Chrome: Title "Cyclonic Wind Vortex · quiver-basic · python · plotly · anyplot.ai", axis titles "X Position (km)" / "Y Position (km)", tick labels, and the "Wind Speed (m/s)" colorbar title/ticks are all dark ink and clearly readable against the light background. + Data: A 13x13 grid of brand-green (#009E73) arrows forms a counterclockwise rotational flow pattern (consistent with u=-y, v=x). All arrows appear visually uniform in length -- length does not vary with vector magnitude in this render. Underlying scatter markers at each arrow base use the green-to-blue sequential imprint_seq gradient keyed to wind speed; the colorbar spans only 0 to ~2.8 m/s. + Legibility verdict: PASS (all text readable, no light-on-light issues). + IMPORTANT: directly executing the current committed source (plots/quiver-basic/implementations/python/plotly.py at HEAD, commit e3d18ee5b) produces a materially different render -- arrow length clearly increasing from the vortex centre outward, and a colorbar spanning 0-28.3 m/s. Re-rendering the PRE-repair commit (dd432f135) instead reproduces this plot-light.png pixel-for-pixel. This proves the supplied render is stale (attempt-1, pre-repair), not the output of the current source. Dark render (plot-dark.png): - Background: Warm near-black, matches #1A1A17 -- not pure black. - Chrome: Title, axis titles, and colorbar title switch to light ink (#F0EFE8) and are clearly visible. Tick labels and colorbar ticks switch to the lighter soft-gray token (#B8B7B0) and remain legible. Gridlines and the zero-line are visible but subtle against the dark surface. No dark-on-dark text anywhere. - Data: Arrow color (#009E73) and the scatter marker green-to-blue gradient are pixel-identical to the light render -- only the chrome (background, text, grid) flipped, confirming palette consistency across themes. - Legibility verdict: PASS -- all text is clearly readable against the dark background; no dark-on-dark failures detected. + Background: Warm near-black, consistent with #1A1A17. Correct, not pure black. + Chrome: Title, axis titles, tick labels, and colorbar text switch to light ink / soft light-gray tokens and remain clearly legible. + Data: Arrow color (#009E73) and the scatter-marker green-to-blue gradient are pixel-identical to the light render -- only chrome flipped, as required. Same uniform arrow-length and 0-2.8 m/s colorbar issue as the light render (i.e. also a stale, pre-repair artifact). + Legibility verdict: PASS (all text readable, no dark-on-dark failures). + + Both renders are internally theme-correct, but both are confirmed stale relative to the current commit -- see the pipeline-failure note in the review weaknesses. criteria_checklist: visual_quality: - score: 27 + score: 26 max: 30 items: - id: VQ-01 @@ -79,73 +84,78 @@ review: score: 7 max: 8 passed: true - comment: All font sizes explicitly set (title fontsize scaled to title length, - axis/tick/colorbar sizes fixed); readable in both themes with no overflow - or clipping. + comment: All font sizes explicitly set (title scales with length, axis/tick/colorbar + sizes fixed); readable in both themes - id: VQ-02 name: No Overlap score: 6 max: 6 passed: true - comment: No text overlaps other text, data, or the colorbar in either render. + comment: No overlap between text, arrows, markers, or colorbar - id: VQ-03 name: Element Visibility - score: 5 + score: 4 max: 6 - passed: true - comment: Arrows and 10px scatter markers are visible for a 225-arrow grid; - density is reasonable though the field reads slightly busy. + passed: false + comment: As rendered, all arrows are the same length so the magnitude encoding + channel is invisible in the arrow field itself (only the color overlay conveys + magnitude); source already fixes this but the fix is not reflected in the + provided render - id: VQ-04 name: Color Accessibility score: 2 max: 2 passed: true - comment: Imprint palette is CVD-safe; green-to-blue gradient plus arrow direction - gives redundant, non-red-green encoding. + comment: Green-to-blue sequential gradient is CVD-safe, good contrast against + both surfaces - id: VQ-05 name: Layout & Canvas score: 3 max: 4 passed: true - comment: Plot fills a good share of the square canvas; extra right margin - for the colorbar leaves the plot slightly left-of-center. + comment: 2400x2400 canvas confirmed (gate passed), balanced margins, minor + left-of-center bias from colorbar reservation - id: VQ-06 name: Axis Labels & Title score: 2 max: 2 passed: true - comment: Axis titles and colorbar title include units (km, m/s). + comment: X/Y Position (km) with units, colorbar labeled with units - id: VQ-07 name: Palette Compliance score: 2 max: 2 passed: true - comment: 'First/only categorical series is #009E73; continuous magnitude correctly - uses imprint_seq (single-polarity data); both renders theme-correct.' + comment: 'First series #009E73, continuous data uses imprint_seq, theme-correct + chrome in both renders' design_excellence: - score: 13 + score: 12 max: 20 items: - id: DE-01 name: Aesthetic Sophistication score: 5 max: 8 - comment: Above a bare default -- custom palette and an intentional two-layer - composition -- but the dense uniform-length arrow grid limits polish. + passed: false + comment: Above default via colorbar overlay composition, but dense uniform + grid in the provided render limits polish - id: DE-02 name: Visual Refinement score: 4 max: 6 - comment: Subtle grid, default L-shaped spines, reasonable whitespace; colorbar - margin slightly unbalances the layout. + passed: false + comment: Subtle grid, reasonable spines/margins; colorbar sizing tightened + since attempt 1 - id: DE-03 name: Data Storytelling - score: 4 + score: 3 max: 6 - comment: Color gradient from calm green center to faster blue edge creates - a clear visual hierarchy and focal point at the vortex core. + passed: false + comment: Color gradient from calm centre to faster edge creates a focal point, + but no visible advancement over attempt 1's storytelling in the render under + review spec_compliance: - score: 13 + score: 12 max: 15 items: - id: SC-01 @@ -153,54 +163,54 @@ review: score: 5 max: 5 passed: true - comment: Correct quiver plot via ff.create_quiver with accurate directional - field. + comment: Correct quiver/vector-field plot via ff.create_quiver - id: SC-02 name: Required Features - score: 2 + score: 1 max: 4 passed: false - comment: Spec requires arrow length proportional to magnitude; implementation - normalizes all arrows to a fixed length, so this required feature is not - represented in the arrows themselves (only via a separate color channel). + comment: Spec requires arrow length proportional to magnitude; not visible + in the provided render (all arrows uniform length) for the second consecutive + review cycle -- though already fixed in the current source per weaknesses + note - id: SC-03 name: Data Mapping score: 3 max: 3 passed: true - comment: x/y correctly mapped to position, u/v correctly mapped to direction; - axes show the full -2..2 grid. + comment: X/Y correctly mapped, full grid visible - id: SC-04 name: Title & Legend score: 3 max: 3 passed: true - comment: Title matches '{Descriptive Title} · spec-id · python · plotly · - anyplot.ai' format; colorbar serves as the legend and is correctly labeled. + comment: Title format correct, colorbar label matches data data_quality: - score: 12 + score: 10 max: 15 items: - id: DQ-01 name: Feature Coverage - score: 4 + score: 3 max: 6 - comment: Shows direction and relative magnitude via color, but the length-based - magnitude feature central to quiver plots is missing from the arrows. + passed: false + comment: Magnitude only encoded via color in the provided render, not via + arrow length -- the primary quiver-plot channel -- for the second consecutive + review cycle - id: DQ-02 name: Realistic Context score: 5 max: 5 passed: true - comment: Meteorology / coastal wind vortex is a neutral, comprehensible, real-world - scenario. + comment: Coastal wind vortex is a realistic, neutral scenario - id: DQ-03 name: Appropriate Scale - score: 3 + score: 2 max: 4 - comment: Values are plausible as numbers but the 0-2.83 m/s range is too gentle - (light-air/breeze) to be physically representative of a 'cyclonic' wind - vortex. + passed: false + comment: Wind speeds in the provided render (0-2.83 m/s) remain too gentle + for a 'cyclonic' vortex -- though already fixed in the current source (peak + ~28 m/s) per weaknesses note code_quality: score: 10 max: 10 @@ -210,55 +220,54 @@ review: score: 3 max: 3 passed: true - comment: Linear script, no functions/classes. + comment: Single top-to-bottom script, no functions/classes - id: CQ-02 name: Reproducibility score: 2 max: 2 passed: true - comment: np.random.seed(42) set; data generation is deterministic. + comment: np.random.seed(42) set - id: CQ-03 name: Clean Imports score: 2 max: 2 passed: true - comment: Only os, numpy, plotly.figure_factory, plotly.graph_objects -- all - used. + comment: Only numpy, plotly.figure_factory, plotly.graph_objects used - id: CQ-04 name: Code Elegance score: 2 max: 2 passed: true - comment: Clean, appropriately complex, no fake functionality. + comment: Clean, appropriately complex, no fake functionality - id: CQ-05 name: Output & API score: 1 max: 1 passed: true - comment: Saves plot-{THEME}.png and plot-{THEME}.html via current write_image/write_html - API. + comment: Saves plot-{THEME}.png and plot-{THEME}.html correctly library_mastery: - score: 7 + score: 6 max: 10 items: - id: LM-01 name: Idiomatic Usage score: 4 max: 5 - comment: Uses plotly's dedicated figure_factory quiver API plus a layered - go.Scatter trace, following the library's recommended high-level patterns. + passed: true + comment: ff.create_quiver plus layered go.Scatter is idiomatic plotly usage - id: LM-02 name: Distinctive Features - score: 3 + score: 2 max: 5 - comment: Combining create_quiver with a colorbar-driven scatter overlay is - a plotly-specific composition technique beyond generic usage. + passed: false + comment: create_quiver + colorbar-driven scatter overlay is plotly-specific + but no new distinctive feature added since attempt 1 verdict: REJECTED impl_tags: dependencies: [] techniques: - colorbar - - layer-composition + - html-export patterns: - data-generation - matrix-construction @@ -266,3 +275,4 @@ impl_tags: - normalization styling: - custom-colormap + - alpha-blending From dd3a0d7e3b7febfcdc29d838a8639201d124a683 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 24 Jul 2026 18:32:49 +0000 Subject: [PATCH 6/7] fix(plotly): address review feedback for quiver-basic Attempt 2/4 - fixes based on AI review --- plots/quiver-basic/implementations/python/plotly.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plots/quiver-basic/implementations/python/plotly.py b/plots/quiver-basic/implementations/python/plotly.py index d97babce7e..0d833e73e8 100644 --- a/plots/quiver-basic/implementations/python/plotly.py +++ b/plots/quiver-basic/implementations/python/plotly.py @@ -1,4 +1,4 @@ -""" anyplot.ai +"""anyplot.ai quiver-basic: Basic Quiver Plot Library: plotly 6.9.0 | Python 3.13.14 Quality: 76/100 | Updated: 2026-07-24 From f09ce3b318c4889efd9bbe14c46cd051fd46ee31 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 24 Jul 2026 18:38:20 +0000 Subject: [PATCH 7/7] chore(plotly): update quality score 85 and review feedback for quiver-basic --- .../implementations/python/plotly.py | 4 +- .../quiver-basic/metadata/python/plotly.yaml | 227 +++++++++--------- 2 files changed, 110 insertions(+), 121 deletions(-) diff --git a/plots/quiver-basic/implementations/python/plotly.py b/plots/quiver-basic/implementations/python/plotly.py index 0d833e73e8..f1891d93eb 100644 --- a/plots/quiver-basic/implementations/python/plotly.py +++ b/plots/quiver-basic/implementations/python/plotly.py @@ -1,7 +1,7 @@ -"""anyplot.ai +""" anyplot.ai quiver-basic: Basic Quiver Plot Library: plotly 6.9.0 | Python 3.13.14 -Quality: 76/100 | Updated: 2026-07-24 +Quality: 85/100 | Updated: 2026-07-24 """ import os diff --git a/plots/quiver-basic/metadata/python/plotly.yaml b/plots/quiver-basic/metadata/python/plotly.yaml index 82be9dd55b..b297e40908 100644 --- a/plots/quiver-basic/metadata/python/plotly.yaml +++ b/plots/quiver-basic/metadata/python/plotly.yaml @@ -2,7 +2,7 @@ library: plotly language: python specification_id: quiver-basic created: '2025-12-23T18:12:55Z' -updated: '2026-07-24T18:28:02Z' +updated: '2026-07-24T18:38:20Z' generated_by: claude-sonnet workflow_run: 30115323638 issue: 1014 @@ -12,71 +12,61 @@ preview_url_light: https://storage.googleapis.com/anyplot-images/plots/quiver-ba preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/quiver-basic/python/plotly/plot-dark.png preview_html_light: https://storage.googleapis.com/anyplot-images/plots/quiver-basic/python/plotly/plot-light.html preview_html_dark: https://storage.googleapis.com/anyplot-images/plots/quiver-basic/python/plotly/plot-dark.html -quality_score: 76 +quality_score: 85 review: strengths: - - 'Correct plot type: ff.create_quiver renders a true quiver field with direction - correctly derived from u=-y, v=x (counterclockwise rotation), matching the described - cyclonic vortex.' - - 'Theme handling is fully correct in both provided renders: PAGE_BG, INK, INK_SOFT, - and GRID all branch on ANYPLOT_THEME and match the required #FAF8F1/#1A1A17 hex - values with no dark-on-dark or light-on-light failures.' - - 'Imprint palette compliance: arrows use brand green #009E73, and the magnitude - overlay correctly uses the sequential imprint_seq colormap (green to blue) since - wind speed is single-polarity data, not the diverging scale.' - - 'Reading the current source directly (plots/quiver-basic/implementations/python/plotly.py - at HEAD) confirms the attempt-1 weaknesses were genuinely addressed in code: arrow - length now scales with relative magnitude via length_frac, and WIND_SPEED_SCALE=10.0 - pushes peak wind speed into a plausible cyclone range (~28 m/s). This is good, - correct engineering work by the repair step.' - - 'Clean, KISS-structured code: single top-to-bottom script, no functions/classes, - deterministic data generation (np.random.seed(42)), only necessary imports.' + - 'Both previously-flagged blockers are now genuinely fixed and visible in the fresh + renders: arrow length grows radially from the calm vortex centre outward (length_frac + formula), and peak wind speed now reaches ~28.3 m/s (WIND_SPEED_SCALE=10.0), a + plausible severe-storm range instead of a light breeze.' + - Direction correctly derived from u=-y, v=x, producing a clean counterclockwise + cyclonic rotation that matches the spec's example field. + - 'Smart redundant encoding: a go.Scatter layer colored by true wind-speed magnitude + (imprint_seq colorscale + colorbar) sits on top of ff.create_quiver, giving a + second, more precise magnitude read that plain create_quiver can''t provide on + its own.' + - 'Theme handling is fully correct in both renders: PAGE_BG/INK/INK_SOFT/GRID all + branch on ANYPLOT_THEME and match the required #FAF8F1/#1A1A17 hex values with + no dark-on-dark or light-on-light failures.' + - 'Imprint palette compliance: arrows use brand green #009E73, and the single-polarity + magnitude field correctly uses imprint_seq rather than a diverging or forbidden + colormap.' + - All font sizes explicitly set (title, axis titles, tick labels, colorbar title/ticks), + with the title fontsize dynamically scaled by a documented length ratio so the + long mandated title never clips. + - Clean, KISS-structured, deterministic script with only the imports actually used. weaknesses: - - 'CRITICAL - PIPELINE FAILURE, not a code defect: the plot-light.png / plot-dark.png - supplied for this review do not reflect the current commit (e3d18ee5b). Evidence: - (1) the colorbar in the provided renders tops out at ~2.8 m/s, but directly executing - the current plots/quiver-basic/implementations/python/plotly.py locally (ANYPLOT_THEME=light) - produces a colorbar spanning 0-28.3 m/s, matching WIND_SPEED_SCALE=10.0 in the - current source. (2) the provided renders show every arrow at a visually uniform - length, but executing the current source produces arrows whose length clearly - grows from the vortex centre outward, matching the length_frac formula in the - current source. (3) rendering the PRE-repair commit (dd432f135) locally reproduces - the provided plot-light.png pixel-for-pixel (same 0-2.8 m/s colorbar, same uniform - arrow lengths, same marker size/opacity). This proves the images attached to this - PR for review are the stale attempt-1 (pre-repair) render, not the output of the - fix that was actually committed. Do NOT make further code edits to fix arrow-length-proportionality - or wind-speed-realism -- both are already correctly implemented in the current - source. Instead the workflow must re-render plot-light.png/plot-dark.png from - the current HEAD commit before the next AI review, or this repair loop will keep - scoring against a stale artifact and can never converge.' - - 'As shown in the (stale) provided renders: every arrow is the same length regardless - of position, so the spec''s ''length proportional to magnitude'' requirement is - not visible in what was reviewed -- though this is understood to already be fixed - in the underlying source per the note above.' - - 'As shown in the (stale) provided renders: wind speed only reaches ~2.8 m/s (light-air - range), too gentle for a ''cyclonic'' vortex -- though this is understood to already - be fixed in the underlying source (peak ~28 m/s) per the note above.' - - Cannot fully evaluate Design Excellence / Library Mastery improvements for this - attempt since the visual artifact under review is unchanged from attempt 1 -- - re-review once fresh renders are available. + - np.random.seed(42) is set but never used - all data (grid, u, v) is generated + deterministically via np.linspace/meshgrid with no calls into np.random. This + is harmless dead code but misleadingly implies a stochastic data-generation step + that doesn't exist; remove the seed line or use it if randomness is ever added. + - 'Design Excellence is solid but not exceptional: the 169-arrow grid plus overlaid + scatter dots is still fairly close to a well-composed default rather than a distinctively + art-directed chart. Consider a slightly more restrained marker opacity/size or + thinner arrow lines near the dense outer rings to let the vortex structure read + even more cleanly as a focal point.' + - The colorbar's reserved right-hand margin makes the square plot area sit marginally + left-of-center; tightening the colorbar thickness/length slightly further would + perfect the whitespace balance (currently good, not perfect). + - Outer-ring arrowheads sit close to their neighbors given the grid spacing versus + max arrow length (~0.32 vs ~0.33 spacing) - not true overlap, but there is little + breathing room; a slightly lower scale_factor would give more visual air without + losing the magnitude signal. image_description: |- Light render (plot-light.png): - Background: Warm off-white, consistent with #FAF8F1. Correct, not pure white. - Chrome: Title "Cyclonic Wind Vortex · quiver-basic · python · plotly · anyplot.ai", axis titles "X Position (km)" / "Y Position (km)", tick labels, and the "Wind Speed (m/s)" colorbar title/ticks are all dark ink and clearly readable against the light background. - Data: A 13x13 grid of brand-green (#009E73) arrows forms a counterclockwise rotational flow pattern (consistent with u=-y, v=x). All arrows appear visually uniform in length -- length does not vary with vector magnitude in this render. Underlying scatter markers at each arrow base use the green-to-blue sequential imprint_seq gradient keyed to wind speed; the colorbar spans only 0 to ~2.8 m/s. - Legibility verdict: PASS (all text readable, no light-on-light issues). - IMPORTANT: directly executing the current committed source (plots/quiver-basic/implementations/python/plotly.py at HEAD, commit e3d18ee5b) produces a materially different render -- arrow length clearly increasing from the vortex centre outward, and a colorbar spanning 0-28.3 m/s. Re-rendering the PRE-repair commit (dd432f135) instead reproduces this plot-light.png pixel-for-pixel. This proves the supplied render is stale (attempt-1, pre-repair), not the output of the current source. + Background: Warm off-white, consistent with #FAF8F1 - not pure white, not dark. + Chrome: Title "Cyclonic Wind Vortex · quiver-basic · python · plotly · anyplot.ai" in dark ink, clearly readable and centered. Axis titles "X Position (km)" / "Y Position (km)" and tick labels are dark/soft-dark ink, all legible. Grid lines are a subtle light gray, visible but not dominant. Colorbar title "Wind Speed (m/s)" and its tick labels (0-25+) are dark ink, fully readable. + Data: A 13x13 grid of brand-green (#009E73) arrows forms a counterclockwise rotational flow pattern (u=-y, v=x). Arrow length clearly grows from short near the calm vortex centre to long at the outer edge, proportional to true wind-speed magnitude. Scatter markers at each arrow base use the green-to-blue imprint_seq sequential gradient keyed to the same magnitude (0 to ~28.3 m/s), growing bluer toward the edges - first-series green confirmed. + Legibility verdict: PASS - all text is readable against the light background, no light-on-light issues. Dark render (plot-dark.png): - Background: Warm near-black, consistent with #1A1A17. Correct, not pure black. - Chrome: Title, axis titles, tick labels, and colorbar text switch to light ink / soft light-gray tokens and remain clearly legible. - Data: Arrow color (#009E73) and the scatter-marker green-to-blue gradient are pixel-identical to the light render -- only chrome flipped, as required. Same uniform arrow-length and 0-2.8 m/s colorbar issue as the light render (i.e. also a stale, pre-repair artifact). - Legibility verdict: PASS (all text readable, no dark-on-dark failures). - - Both renders are internally theme-correct, but both are confirmed stale relative to the current commit -- see the pipeline-failure note in the review weaknesses. + Background: Warm near-black, consistent with #1A1A17 - not pure black, not light. + Chrome: Title, axis titles, tick labels, and colorbar title/ticks all switch to light ink / soft light-gray tokens and remain clearly legible. Grid lines flip to a subtle light-on-dark tone, still subtle but visible. + Data: Arrow color (#009E73) and the green-to-blue scatter gradient are pixel-identical to the light render - only chrome flipped, as required. Same radially-growing arrow length and same 0-28.3 m/s colorbar range as the light render. + Legibility verdict: PASS - all text is readable against the dark background; no dark-on-dark failures (no black-on-near-black text anywhere). criteria_checklist: visual_quality: - score: 26 + score: 27 max: 30 items: - id: VQ-01 @@ -84,52 +74,50 @@ review: score: 7 max: 8 passed: true - comment: All font sizes explicitly set (title scales with length, axis/tick/colorbar - sizes fixed); readable in both themes + comment: All font sizes explicitly set (title dynamically scaled to length); + readable in both themes with no overflow or clipping - id: VQ-02 name: No Overlap score: 6 max: 6 passed: true - comment: No overlap between text, arrows, markers, or colorbar + comment: No text overlaps other text, data, or the colorbar - id: VQ-03 name: Element Visibility - score: 4 + score: 5 max: 6 - passed: false - comment: As rendered, all arrows are the same length so the magnitude encoding - channel is invisible in the arrow field itself (only the color overlay conveys - magnitude); source already fixes this but the fix is not reflected in the - provided render + passed: true + comment: Arrow length now correctly scales with relative magnitude (previously + flagged, now fixed); outer-ring arrowheads sit fairly close together - id: VQ-04 name: Color Accessibility score: 2 max: 2 passed: true - comment: Green-to-blue sequential gradient is CVD-safe, good contrast against - both surfaces + comment: Green arrows and blue-green sequential gradient are distinguishable + from the warm backgrounds in both themes; no red-green reliance - id: VQ-05 name: Layout & Canvas score: 3 max: 4 passed: true - comment: 2400x2400 canvas confirmed (gate passed), balanced margins, minor - left-of-center bias from colorbar reservation + comment: Plot fills a healthy majority of the square canvas with balanced + margins; colorbar reserve makes the plot area sit marginally left-of-center - id: VQ-06 name: Axis Labels & Title score: 2 max: 2 passed: true - comment: X/Y Position (km) with units, colorbar labeled with units + comment: '"X Position (km)" / "Y Position (km)" - descriptive with units' - id: VQ-07 name: Palette Compliance score: 2 max: 2 passed: true - comment: 'First series #009E73, continuous data uses imprint_seq, theme-correct - chrome in both renders' + comment: 'First (only) series is #009E73; continuous magnitude correctly uses + imprint_seq (single-polarity); theme-correct chrome in both renders' design_excellence: - score: 12 + score: 13 max: 20 items: - id: DE-01 @@ -137,25 +125,24 @@ review: score: 5 max: 8 passed: false - comment: Above default via colorbar overlay composition, but dense uniform - grid in the provided render limits polish + comment: Above a bare default via the layered quiver+colorbar composition, + but still short of publication-level polish - id: DE-02 name: Visual Refinement score: 4 max: 6 passed: false - comment: Subtle grid, reasonable spines/margins; colorbar sizing tightened - since attempt 1 + comment: Subtle grid, tightened colorbar sizing since attempt 1, reasonable + margins - id: DE-03 name: Data Storytelling - score: 3 + score: 4 max: 6 passed: false - comment: Color gradient from calm centre to faster edge creates a focal point, - but no visible advancement over attempt 1's storytelling in the render under - review + comment: Length AND color both now grow from the calm centre outward, reinforcing + a clear visual hierarchy/focal point spec_compliance: - score: 12 + score: 15 max: 15 items: - id: SC-01 @@ -163,56 +150,54 @@ review: score: 5 max: 5 passed: true - comment: Correct quiver/vector-field plot via ff.create_quiver + comment: True quiver field via ff.create_quiver - id: SC-02 name: Required Features - score: 1 + score: 4 max: 4 - passed: false - comment: Spec requires arrow length proportional to magnitude; not visible - in the provided render (all arrows uniform length) for the second consecutive - review cycle -- though already fixed in the current source per weaknesses - note + passed: true + comment: Arrow length now proportional to magnitude (previously the key gap), + uniform grid spacing, optional magnitude-by-color present - id: SC-03 name: Data Mapping score: 3 max: 3 passed: true - comment: X/Y correctly mapped, full grid visible + comment: x/y correctly assigned; full grid range visible on both axes - id: SC-04 name: Title & Legend score: 3 max: 3 passed: true - comment: Title format correct, colorbar label matches data + comment: Title matches "{Descriptive Title} · quiver-basic · python · plotly + · anyplot.ai"; no legend needed (single series) data_quality: - score: 10 + score: 14 max: 15 items: - id: DQ-01 name: Feature Coverage - score: 3 + score: 5 max: 6 - passed: false - comment: Magnitude only encoded via color in the provided render, not via - arrow length -- the primary quiver-plot channel -- for the second consecutive - review cycle + passed: true + comment: Shows direction, magnitude-by-length, and magnitude-by-color, including + the near-zero calm-centre edge case - id: DQ-02 name: Realistic Context score: 5 max: 5 passed: true - comment: Coastal wind vortex is a realistic, neutral scenario + comment: Cyclonic wind vortex over a coastal grid - real, neutral meteorology + scenario - id: DQ-03 name: Appropriate Scale - score: 2 + score: 4 max: 4 - passed: false - comment: Wind speeds in the provided render (0-2.83 m/s) remain too gentle - for a 'cyclonic' vortex -- though already fixed in the current source (peak - ~28 m/s) per weaknesses note + passed: true + comment: Peak wind speed ~28.3 m/s is a plausible severe-storm range, fixing + the previous light-breeze issue code_quality: - score: 10 + score: 9 max: 10 items: - id: CQ-01 @@ -220,33 +205,36 @@ review: score: 3 max: 3 passed: true - comment: Single top-to-bottom script, no functions/classes + comment: Flat top-to-bottom script, no functions/classes - id: CQ-02 name: Reproducibility score: 2 max: 2 passed: true - comment: np.random.seed(42) set + comment: Fully deterministic grid/vector generation - id: CQ-03 name: Clean Imports score: 2 max: 2 passed: true - comment: Only numpy, plotly.figure_factory, plotly.graph_objects used + comment: Only numpy, plotly.figure_factory, plotly.graph_objects, os, sys + - all used - id: CQ-04 name: Code Elegance - score: 2 + score: 1 max: 2 - passed: true - comment: Clean, appropriately complex, no fake functionality + passed: false + comment: np.random.seed(42) is set but never used (no np.random calls exist) + - harmless but misleading dead code - id: CQ-05 name: Output & API score: 1 max: 1 passed: true - comment: Saves plot-{THEME}.png and plot-{THEME}.html correctly + comment: write_image(f'plot-{THEME}.png', width=600, height=600, scale=4) + + write_html - correct API, correct canvas library_mastery: - score: 6 + score: 7 max: 10 items: - id: LM-01 @@ -254,20 +242,21 @@ review: score: 4 max: 5 passed: true - comment: ff.create_quiver plus layered go.Scatter is idiomatic plotly usage + comment: ff.create_quiver is plotly's dedicated high-level quiver API, correctly + parameterized - id: LM-02 name: Distinctive Features - score: 2 + score: 3 max: 5 passed: false - comment: create_quiver + colorbar-driven scatter overlay is plotly-specific - but no new distinctive feature added since attempt 1 - verdict: REJECTED + comment: create_quiver + a layered go.Scatter colorbar overlay is a plotly-specific + composition that isn't trivially replicated in other libraries + verdict: APPROVED impl_tags: dependencies: [] techniques: - colorbar - - html-export + - layer-composition patterns: - data-generation - matrix-construction