diff --git a/plots/rose-basic/implementations/python/plotly.py b/plots/rose-basic/implementations/python/plotly.py index 4110d34575..29940b8517 100644 --- a/plots/rose-basic/implementations/python/plotly.py +++ b/plots/rose-basic/implementations/python/plotly.py @@ -1,64 +1,75 @@ -""" pyplots.ai +""" anyplot.ai rose-basic: Basic Rose Chart -Library: plotly 6.5.0 | Python 3.13.11 -Quality: 91/100 | Created: 2025-12-23 +Library: plotly 6.7.0 | Python 3.13.13 +Quality: 90/100 | Updated: 2026-04-30 """ +import os + import plotly.graph_objects as go -# Data - Monthly rainfall (mm) showing seasonal pattern +# Theme tokens +THEME = os.getenv("ANYPLOT_THEME", "light") +PAGE_BG = "#FAF8F1" if THEME == "light" else "#1A1A17" +ELEVATED_BG = "#FFFDF6" if THEME == "light" else "#242420" +INK = "#1A1A17" if THEME == "light" else "#F0EFE8" +INK_SOFT = "#4A4A44" if THEME == "light" else "#B8B7B0" +GRID = "rgba(26,26,23,0.10)" if THEME == "light" else "rgba(240,239,232,0.10)" + +# Data - Monthly rainfall (mm) showing pronounced seasonal pattern months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] -rainfall = [78, 62, 55, 48, 42, 38, 35, 40, 52, 68, 82, 85] +rainfall = [92, 74, 60, 45, 32, 18, 12, 22, 48, 75, 98, 105] -# Create the rose chart using barpolar -# Using month names directly as theta (categorical) for proper label placement +# Plot fig = go.Figure() fig.add_trace( go.Barpolar( r=rainfall, theta=months, - width=0.9, # Slight gap between bars for visual clarity + width=0.9, marker={ "color": rainfall, - "colorscale": [[0, "#FFD43B"], [1, "#306998"]], # Python Yellow to Blue - "line": {"color": "white", "width": 2}, - "cmin": min(rainfall), + "colorscale": "viridis", + "line": {"color": PAGE_BG, "width": 2}, + "cmin": 0, "cmax": max(rainfall), }, hovertemplate="%{theta}
Rainfall: %{r} mm", ) ) -# Update layout for 4800x2700 px output fig.update_layout( - title={"text": "rose-basic · plotly · pyplots.ai", "font": {"size": 48}, "x": 0.5, "xanchor": "center"}, - template="plotly_white", + title={ + "text": "rose-basic · plotly · anyplot.ai", + "font": {"size": 48, "color": INK}, + "x": 0.5, + "xanchor": "center", + }, + paper_bgcolor=PAGE_BG, polar={ + "bgcolor": PAGE_BG, "angularaxis": { - "tickfont": {"size": 28}, + "tickfont": {"size": 28, "color": INK_SOFT}, "direction": "clockwise", - "rotation": 90, # Start at top (12 o'clock) - "gridcolor": "rgba(0,0,0,0.1)", - "linecolor": "rgba(0,0,0,0.3)", + "rotation": 90, + "gridcolor": GRID, + "linecolor": INK_SOFT, }, "radialaxis": { - "tickfont": {"size": 22}, - "gridcolor": "rgba(0,0,0,0.15)", - "linecolor": "rgba(0,0,0,0.3)", + "tickfont": {"size": 22, "color": INK_SOFT}, + "gridcolor": GRID, + "linecolor": INK_SOFT, "ticksuffix": " mm", "angle": 45, - "dtick": 20, + "dtick": 25, }, - "bgcolor": "white", }, showlegend=False, margin={"l": 100, "r": 100, "t": 150, "b": 100}, ) -# Save as PNG (4800 x 2700 px) -fig.write_image("plot.png", width=1600, height=900, scale=3) - -# Save interactive HTML version -fig.write_html("plot.html", include_plotlyjs="cdn") +# Save +fig.write_image(f"plot-{THEME}.png", width=1600, height=900, scale=3) +fig.write_html(f"plot-{THEME}.html", include_plotlyjs="cdn") diff --git a/plots/rose-basic/metadata/python/plotly.yaml b/plots/rose-basic/metadata/python/plotly.yaml index 994131e6c6..8e194a59d8 100644 --- a/plots/rose-basic/metadata/python/plotly.yaml +++ b/plots/rose-basic/metadata/python/plotly.yaml @@ -1,169 +1,182 @@ library: plotly +language: python specification_id: rose-basic created: '2025-12-23T19:43:10Z' -updated: '2025-12-23T19:50:42Z' -generated_by: claude-opus-4-5-20251101 -workflow_run: 20469992414 -issue: 0 -python_version: 3.13.11 -library_version: 6.5.0 -preview_url: https://storage.googleapis.com/anyplot-images/plots/rose-basic/plotly/plot.png -preview_html: https://storage.googleapis.com/anyplot-images/plots/rose-basic/plotly/plot.html -quality_score: 91 -impl_tags: - dependencies: [] - techniques: - - html-export - - hover-tooltips - - custom-colormap - patterns: - - data-generation - dataprep: [] - styling: [] +updated: '2026-04-30T07:07:15Z' +generated_by: claude-sonnet +workflow_run: 25151743773 +issue: 1003 +python_version: 3.13.13 +library_version: 6.7.0 +preview_url_light: https://storage.googleapis.com/anyplot-images/plots/rose-basic/python/plotly/plot-light.png +preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/rose-basic/python/plotly/plot-dark.png +preview_html_light: https://storage.googleapis.com/anyplot-images/plots/rose-basic/python/plotly/plot-light.html +preview_html_dark: https://storage.googleapis.com/anyplot-images/plots/rose-basic/python/plotly/plot-dark.html +quality_score: 90 review: strengths: - - Excellent use of plotly's barpolar trace type for creating the rose chart - - Proper clockwise direction with rotation starting at 12 o'clock position (as spec - recommends for time data) - - Beautiful Python-themed color gradient (yellow to blue) that is colorblind-accessible - - White borders between segments enhance visual distinction - - Includes both PNG and interactive HTML output, leveraging plotly's interactivity - - Custom hover template with mm units provides useful tooltip information - - Radial axis tick suffix mm makes values self-documenting + - Native go.Barpolar trace with full polar axis configuration; idiomatic and correct + Plotly usage + - Viridis double-encoding (both radius and color encode rainfall value) is a thoughtful + design choice that reinforces the seasonal pattern + - 'Complete theme adaptation: correct backgrounds (#FAF8F1/#1A1A17), all chrome + tokens applied to polar axis, legend, title' + - Deterministic Mediterranean rainfall data is a textbook-quality rose chart example + with clear cyclical insight + - 'Full Plotly interactivity preserved: rich hovertemplate, HTML export alongside + PNG' weaknesses: - - Radial axis label text is angled and slightly harder to read than if horizontal - - Data range is somewhat narrow (35-85mm); more extreme variation would better showcase - the plot type - - Could add a subtitle or annotation explaining the data context - image_description: The plot displays a rose/coxcomb chart showing monthly rainfall - data. It features 12 wedge-shaped segments arranged in a circle, one for each - month (Jan through Dec), starting from the top at 12 o'clock position and proceeding - clockwise. The segments' radii correspond to rainfall values in mm. The color - scheme transitions from yellow (Python Yellow, ~#FFD43B) for lower values to blue - (Python Blue, ~#306998) for higher values. July has the smallest radius (~35mm, - yellow), while December has the largest (~85mm, blue). Radial gridlines at 0, - 20, 40, 60, and 80 mm help gauge values. The title "rose-basic · plotly · pyplots.ai" - appears centered at the top. Month labels are positioned around the outer edge - of the chart. The overall layout is clean with a white background. + - Landscape (16:9) format introduces minor side whitespace for a circular chart; + square format (3600x3600) would better utilize canvas + - Radial tick labels slightly stacked near chart center at 45 degree angle; could + be improved with fewer ticks or adjusted label placement + image_description: |- + Light render (plot-light.png): + Background: Warm off-white consistent with #FAF8F1 — not pure white + Chrome: Title 'rose-basic · plotly · anyplot.ai' in dark ink (size 48) fully readable; month labels at 28px in INK_SOFT fully readable around perimeter; radial tick labels (0–100 mm) at 22px readable though somewhat stacked near center + Data: Viridis colorscale applied continuously — dark blue/teal for low-rainfall months (Jun=12mm, Jul=12mm), through teal-green, to yellow for high-rainfall months (Dec=105mm, Nov=98mm); bar edges use PAGE_BG color for clean separation + Legibility verdict: PASS — all text clearly readable against warm off-white background; no light-on-light issues + + Dark render (plot-dark.png): + Background: Warm near-black consistent with #1A1A17 — not pure black + Chrome: Title in light INK (#F0EFE8) clearly readable; month labels in INK_SOFT (#B8B7B0) readable; radial tick labels in INK_SOFT readable; no dark-on-dark failures observed; all text is light-colored on dark background + Data: Viridis colorscale colors are identical to light render — same teal-to-yellow gradient; bar edges use dark PAGE_BG color for definition; data visual is indistinguishable from light render in terms of color identity + Legibility verdict: PASS — all text clearly readable against near-black background; no dark-on-dark issues criteria_checklist: visual_quality: - score: 36 - max: 40 + score: 28 + max: 30 items: - id: VQ-01 name: Text Legibility - score: 10 - max: 10 + score: 8 + max: 8 passed: true - comment: Title is large and clear, month labels are easily readable, radial - axis labels are legible + comment: 'All font sizes explicitly set: title 48px, angular ticks 28px, radial + ticks 22px; fully readable in both themes' - id: VQ-02 name: No Overlap - score: 8 - max: 8 + score: 5 + max: 6 passed: true - comment: No overlapping text elements; month labels well-spaced around the - perimeter + comment: Month labels well-spaced; radial labels slightly cramped near center + but readable - id: VQ-03 name: Element Visibility - score: 7 - max: 8 + score: 6 + max: 6 passed: true - comment: Wedges are clearly visible with good sizing; white borders between - segments aid distinction + comment: Bars clearly visible, seasonal pattern immediately apparent - id: VQ-04 name: Color Accessibility - score: 4 - max: 5 + score: 2 + max: 2 passed: true - comment: Yellow-to-blue gradient is colorblind-friendly (avoids red-green); - good choice + comment: Viridis is CVD-safe and perceptually uniform - id: VQ-05 - name: Layout Balance - score: 4 - max: 5 + name: Layout & Canvas + score: 3 + max: 4 passed: true - comment: Good proportions; chart utilizes canvas well though slightly more - centered vertically than ideal + comment: Chart fills canvas well but landscape 16:9 format introduces side + whitespace for circular plot - id: VQ-06 - name: Axis Labels + name: Axis Labels & Title score: 2 max: 2 passed: true - comment: Radial axis includes unit "mm" suffix; month labels are descriptive + comment: Radial tick suffix mm provides units; title gives context - id: VQ-07 - name: Grid & Legend - score: 1 + name: Palette Compliance + score: 2 max: 2 passed: true - comment: Subtle radial gridlines present; no legend needed for single-series + comment: 'Viridis used correctly for continuous value-mapped data; backgrounds + are #FAF8F1/#1A1A17; all chrome is theme-adaptive' + design_excellence: + score: 13 + max: 20 + items: + - id: DE-01 + name: Aesthetic Sophistication + score: 5 + max: 8 + passed: true + comment: 'Above well-configured defaults: viridis double-encoding is thoughtful, + PAGE_BG separator edges create clean definition, explicit typography; not + yet at strong design level' + - id: DE-02 + name: Visual Refinement + score: 4 + max: 6 + passed: true + comment: Subtle 10% opacity grid, custom bar width 0.9, adaptive edge colors, + explicit generous margins, clockwise orientation from north + - id: DE-03 + name: Data Storytelling + score: 4 + max: 6 + passed: true + comment: Seasonal pattern immediately clear through double-encoding; viewer + instantly sees Nov-Jan wet, Jun-Aug dry spec_compliance: - score: 25 - max: 25 + score: 15 + max: 15 items: - id: SC-01 name: Plot Type - score: 8 - max: 8 - passed: true - comment: Correct rose/coxcomb chart using barpolar - - id: SC-02 - name: Data Mapping score: 5 max: 5 passed: true - comment: Categories (months) on angular axis, values (rainfall) as radius - - correct - - id: SC-03 + comment: go.Barpolar is Plotly's native polar bar (rose) chart type + - id: SC-02 name: Required Features - score: 5 - max: 5 + score: 4 + max: 4 passed: true - comment: Equal-angle wedges, radius proportional to value, circular arrangement - - id: SC-04 - name: Data Range + comment: Circular format, radius proportional to value, radial gridlines, + 12 monthly categories, consistent colorscheme + - id: SC-03 + name: Data Mapping score: 3 max: 3 passed: true - comment: All data visible, radial axis shows full range (0-80+ mm) - - id: SC-05 - name: Legend Accuracy - score: 2 - max: 2 - passed: true - comment: No legend needed; color scale implicit and appropriate - - id: SC-06 - name: Title Format - score: 2 - max: 2 + comment: Months on angular axis, rainfall on radial axis; clockwise from north + (rotation=90) correct for calendar data + - id: SC-04 + name: Title & Legend + score: 3 + max: 3 passed: true - comment: 'Correct format: "rose-basic · plotly · pyplots.ai"' + comment: Title rose-basic · plotly · anyplot.ai correct; no legend needed + for single-series data_quality: - score: 18 - max: 20 + score: 15 + max: 15 items: - id: DQ-01 name: Feature Coverage - score: 7 - max: 8 + score: 6 + max: 6 passed: true - comment: Shows seasonal variation in rainfall; demonstrates high winter/low - summer pattern; could show more extreme outliers + comment: Full range 12-105 mm demonstrates cyclical patterns with prominent + seasonal variation - id: DQ-02 name: Realistic Context - score: 7 - max: 7 + score: 5 + max: 5 passed: true - comment: Monthly rainfall data is a classic rose chart application; values - are realistic for temperate climate + comment: Monthly rainfall is the canonical neutral rose chart example with + clear real-world meaning - id: DQ-03 name: Appropriate Scale score: 4 - max: 5 + max: 4 passed: true - comment: Values 35-85mm are plausible; perhaps slightly narrow range + comment: Annual total ~681 mm with winter-peak pattern consistent with Mediterranean + climate code_quality: - score: 9 + score: 10 max: 10 items: - id: CQ-01 @@ -171,42 +184,60 @@ review: score: 3 max: 3 passed: true - comment: 'Clean linear flow: imports → data → plot → save' + comment: 'Linear: imports, theme tokens, data, plot, save; no functions or + classes' - id: CQ-02 name: Reproducibility score: 2 - max: 3 - passed: false - comment: Data is deterministic (hardcoded values) but no random seed statement - even though not needed + max: 2 + passed: true + comment: Hardcoded deterministic data; no randomness - id: CQ-03 name: Clean Imports score: 2 max: 2 passed: true - comment: Only plotly.graph_objects imported, and used + comment: Only os and plotly.graph_objects imported, both used - id: CQ-04 - name: No Deprecated API - score: 1 - max: 1 + name: Code Elegance + score: 2 + max: 2 passed: true - comment: Uses current plotly API (go.Barpolar) + comment: Clean Pythonic dict-based marker config; appropriate complexity - id: CQ-05 - name: Output Correct + name: Output & API score: 1 max: 1 passed: true - comment: Saves as plot.png with correct dimensions - library_features: - score: 3 - max: 5 + comment: Saves plot-{THEME}.png and plot-{THEME}.html; current Plotly API + library_mastery: + score: 9 + max: 10 items: - - id: LF-01 - name: Uses distinctive library features - score: 3 + - id: LM-01 + name: Idiomatic Usage + score: 5 + max: 5 + passed: true + comment: go.Barpolar with proper polar axis config (angularaxis, radialaxis, + direction, rotation) is idiomatic Plotly + - id: LM-02 + name: Distinctive Features + score: 4 max: 5 passed: true - comment: Uses barpolar for rose chart, hover template for interactivity, and - exports HTML version; could leverage more plotly-specific features like - animations or custom hover data + comment: 'Plotly-distinctive: go.Barpolar trace, hovertemplate for rich interactive + tooltips, write_html for interactive export' verdict: APPROVED +impl_tags: + dependencies: [] + techniques: + - polar-projection + - hover-tooltips + - html-export + patterns: + - data-generation + dataprep: [] + styling: + - custom-colormap + - edge-highlighting