diff --git a/plots/line-filled/implementations/python/bokeh.py b/plots/line-filled/implementations/python/bokeh.py index 81220aacd8..be81d3810f 100644 --- a/plots/line-filled/implementations/python/bokeh.py +++ b/plots/line-filled/implementations/python/bokeh.py @@ -1,15 +1,28 @@ -""" pyplots.ai +""" anyplot.ai line-filled: Filled Line Plot -Library: bokeh 3.8.1 | Python 3.13.11 -Quality: 91/100 | Created: 2025-12-30 +Library: bokeh 3.9.0 | Python 3.13.13 +Quality: 91/100 | Updated: 2026-05-12 """ +import os +import time +from pathlib import Path + import numpy as np -from bokeh.io import export_png, save +from bokeh.io import output_file, save from bokeh.models import ColumnDataSource, HoverTool from bokeh.plotting import figure -from bokeh.resources import CDN +from selenium import webdriver +from selenium.webdriver.chrome.options import Options + +# 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" +BRAND = "#009E73" # Data - Monthly website traffic over a year np.random.seed(42) @@ -29,19 +42,19 @@ p = figure( width=4800, height=2700, - title="line-filled · bokeh · pyplots.ai", + title="line-filled · bokeh · anyplot.ai", x_axis_label="Month", - y_axis_label="Website Visitors", + y_axis_label="Website Visitors (count)", ) # Filled area using varea -p.varea(x="month", y1="traffic_zero", y2="traffic", source=source, fill_color="#306998", fill_alpha=0.4) +p.varea(x="month", y1="traffic_zero", y2="traffic", source=source, fill_color=BRAND, fill_alpha=0.35) # Line on top of the fill -p.line(x="month", y="traffic", source=source, line_color="#306998", line_width=4) +p.line(x="month", y="traffic", source=source, line_color=BRAND, line_width=4) # Add points for visual emphasis -p.scatter(x="month", y="traffic", source=source, size=12, color="#306998", fill_alpha=0.8) +p.scatter(x="month", y="traffic", source=source, size=12, color=BRAND, fill_alpha=0.8) # Add hover tool hover = HoverTool(tooltips=[("Month", "@month"), ("Visitors", "@traffic{0,0}")]) @@ -54,21 +67,53 @@ p.xaxis.major_label_text_font_size = "18pt" p.yaxis.major_label_text_font_size = "18pt" +# Theme-adaptive text colors +p.title.text_color = INK +p.xaxis.axis_label_text_color = INK +p.yaxis.axis_label_text_color = INK +p.xaxis.major_label_text_color = INK_SOFT +p.yaxis.major_label_text_color = INK_SOFT + # Grid styling -p.xgrid.grid_line_alpha = 0.3 -p.ygrid.grid_line_alpha = 0.3 -p.xgrid.grid_line_dash = [6, 4] -p.ygrid.grid_line_dash = [6, 4] +p.xgrid.grid_line_alpha = 0.10 +p.ygrid.grid_line_alpha = 0.10 +p.xgrid.grid_line_color = INK +p.ygrid.grid_line_color = INK + +# Axis styling +p.xaxis.axis_line_color = INK_SOFT +p.yaxis.axis_line_color = INK_SOFT +p.xaxis.major_tick_line_color = INK_SOFT +p.yaxis.major_tick_line_color = INK_SOFT # Background -p.background_fill_color = "#fafafa" -p.border_fill_color = "#ffffff" +p.background_fill_color = PAGE_BG +p.border_fill_color = PAGE_BG +p.outline_line_color = INK_SOFT # X-axis ticks for each month p.xaxis.ticker = list(range(1, 13)) -# Save as PNG and HTML -export_png(p, filename="plot.png") +# Save as interactive HTML +output_file(f"plot-{THEME}.html") +save(p) + +# Screenshot with headless Chrome +W, H = 4800, 2700 +opts = Options() +for arg in ( + "--headless=new", + "--no-sandbox", + "--disable-dev-shm-usage", + "--disable-gpu", + f"--window-size={W},{H}", + "--hide-scrollbars", +): + opts.add_argument(arg) -# Also save interactive HTML -save(p, filename="plot.html", resources=CDN, title="line-filled · bokeh · pyplots.ai") +driver = webdriver.Chrome(options=opts) +driver.set_window_size(W, H) +driver.get(f"file://{Path(f'plot-{THEME}.html').resolve()}") +time.sleep(3) # Let bokeh's JS render the canvas +driver.save_screenshot(f"plot-{THEME}.png") +driver.quit() diff --git a/plots/line-filled/metadata/python/bokeh.yaml b/plots/line-filled/metadata/python/bokeh.yaml index c8cbdec666..5fc1ad1759 100644 --- a/plots/line-filled/metadata/python/bokeh.yaml +++ b/plots/line-filled/metadata/python/bokeh.yaml @@ -1,161 +1,171 @@ library: bokeh +language: python specification_id: line-filled created: '2025-12-30T11:23:14Z' -updated: '2025-12-30T11:35:51Z' -generated_by: claude-opus-4-5-20251101 -workflow_run: 20595334170 -issue: 0 -python_version: 3.13.11 -library_version: 3.8.1 -preview_url: https://storage.googleapis.com/anyplot-images/plots/line-filled/bokeh/plot.png -preview_html: https://storage.googleapis.com/anyplot-images/plots/line-filled/bokeh/plot.html +updated: '2026-05-12T17:06:48Z' +generated_by: claude-haiku +workflow_run: 25749578526 +issue: 2643 +python_version: 3.13.13 +library_version: 3.9.0 +preview_url_light: https://storage.googleapis.com/anyplot-images/plots/line-filled/python/bokeh/plot-light.png +preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/line-filled/python/bokeh/plot-dark.png +preview_html_light: https://storage.googleapis.com/anyplot-images/plots/line-filled/python/bokeh/plot-light.html +preview_html_dark: https://storage.googleapis.com/anyplot-images/plots/line-filled/python/bokeh/plot-dark.html quality_score: 91 -impl_tags: - dependencies: [] - techniques: - - html-export - - hover-tooltips - - columndatasource - patterns: - - data-generation - dataprep: [] - styling: - - alpha-blending - - grid-styling review: strengths: - - Excellent use of Bokeh's varea glyph for the filled area effect - - Clean implementation with ColumnDataSource for data management - - Interactive HTML output with HoverTool showing formatted visitor counts - - Proper font sizing for the 4800x2700 canvas - - Subtle grid styling with dashed lines and low alpha - - Realistic website traffic scenario with seasonal variation + - Perfect visual quality with full theme readability in both light and dark renders + - Correct Okabe-Ito color usage (#009E73) with proper theme adaptation + - Idiomatic bokeh implementation using ColumnDataSource, varea, and interactive + HoverTool + - Full specification compliance with semi-transparent fill, visible line, and y=0 + baseline + - Realistic, well-scaled data with clear seasonal narrative + - Clean, reproducible code with proper font sizing for large canvas weaknesses: - - Axis labels lack units (e.g., "Website Visitors (count)" or "Month of Year") - - Could use more distinctive Bokeh features like CustomJS, band annotations, or - span annotations to highlight peaks - image_description: The plot shows a filled line chart displaying website traffic - (visitors) over 12 months. The area beneath the line is filled with a semi-transparent - blue color (#306998 with alpha 0.4). A solid blue line traces the top of the filled - area, with small circular markers at each data point. The chart shows a seasonal - pattern peaking around month 7 (July) at approximately 81,000 visitors, with lower - values at the start (~40,000) and end (~57,000) of the year. The background is - a light gray (#fafafa), and there is a subtle dashed grid. The title "line-filled - · bokeh · pyplots.ai" appears in the top-left. The x-axis shows months 1-12 labeled - as "Month", and the y-axis shows "Website Visitors" ranging from 0 to ~80,000. - Bokeh toolbar icons are visible in the top-right corner. + - Design excellence could explore spine removal for more minimal aesthetic + - Library mastery could leverage advanced bokeh features (callbacks, custom JS) + image_description: |- + Light render (plot-light.png): + Background: Warm off-white (#FAF8F1), correctly implemented + Chrome: Title, axis labels, tick labels all clearly readable in dark text + Data: Semi-transparent filled area in brand green (#009E73) with solid line on top and scatter points + Legibility verdict: PASS - All elements readable with good contrast + + Dark render (plot-dark.png): + Background: Warm near-black (#1A1A17), correctly implemented + Chrome: Title, axis labels, tick labels adapted to light text, all readable + Data: Colors identical to light render (brand green maintained), no dark-on-dark failures + Legibility verdict: PASS - All elements readable, proper theme adaptation criteria_checklist: visual_quality: - score: 36 - max: 40 + score: 30 + max: 30 items: - id: VQ-01 name: Text Legibility - score: 9 - max: 10 + score: 8 + max: 8 passed: true - comment: Title, axis labels, and tick marks are readable but could be slightly - larger for the canvas size + comment: All text correctly sized (28pt title, 22pt labels, 18pt ticks) and + readable in both light and dark themes - id: VQ-02 name: No Overlap - score: 8 - max: 8 + score: 6 + max: 6 passed: true - comment: No overlapping text elements + comment: Clean layout with no overlapping elements or text collisions - id: VQ-03 name: Element Visibility - score: 8 - max: 8 + score: 6 + max: 6 passed: true - comment: Line, fill, and markers are well-sized and clearly visible + comment: Filled area, line, and scatter points all clearly visible and distinguishable - id: VQ-04 name: Color Accessibility - score: 5 - max: 5 + score: 2 + max: 2 passed: true - comment: Single blue color is colorblind-safe + comment: Brand green (#009E73) is colorblind-safe (Okabe-Ito position 1) with + excellent contrast - id: VQ-05 - name: Layout Balance + name: Layout & Canvas score: 4 - max: 5 + max: 4 passed: true - comment: Good use of canvas, slight imbalance with toolbar in corner + comment: Excellent proportions at 4800×2700 with generous margins and whitespace - id: VQ-06 - name: Axis Labels - score: 1 + name: Axis Labels & Title + score: 2 max: 2 passed: true - comment: Descriptive labels but no units (e.g., "Website Visitors (count)") + comment: Title 'line-filled · bokeh · anyplot.ai' is correctly formatted, + axes descriptive with units - id: VQ-07 - name: Grid & Legend - score: 1 + name: Palette Compliance + score: 2 max: 2 passed: true - comment: Grid is subtle with dashed lines and alpha 0.3, no legend needed - for single series + comment: 'Brand green correct, backgrounds #FAF8F1 (light)/#1A1A17 (dark), + theme-adaptive chrome only' + design_excellence: + score: 14 + max: 20 + items: + - id: DE-01 + name: Aesthetic Sophistication + score: 6 + max: 8 + passed: true + comment: Publication-ready styling with scatter points adding visual interest + to line-fill combination + - id: DE-02 + name: Visual Refinement + score: 4 + max: 6 + passed: true + comment: Subtle grid at 10% opacity, minimal decoration, good whitespace management + - id: DE-03 + name: Data Storytelling + score: 4 + max: 6 + passed: true + comment: Clear seasonal pattern with natural summer peak as focal point, good + visual narrative 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 filled line/area chart - - id: SC-02 - name: Data Mapping score: 5 max: 5 passed: true - comment: X (months) and Y (visitors) correctly mapped - - id: SC-03 + comment: Correct filled line plot (area chart) with proper technique + - id: SC-02 name: Required Features - score: 5 - max: 5 + score: 4 + max: 4 passed: true - comment: Semi-transparent fill, visible line on top, fill matches line color - - id: SC-04 - name: Data Range + comment: Semi-transparent fill (α=0.35, within 0.3–0.5 spec), visible line + on top, matching colors, y=0 baseline + - id: SC-03 + name: Data Mapping score: 3 max: 3 passed: true - comment: All data visible, y-axis starts at 0 (baseline) - - id: SC-05 - name: Legend Accuracy - score: 2 - max: 2 - passed: true - comment: N/A for single series, no legend needed - - id: SC-06 - name: Title Format - score: 2 - max: 2 + comment: Months (1-12) on X-axis, visitors on Y-axis, all data displayed + - id: SC-04 + name: Title & Legend + score: 3 + max: 3 passed: true - comment: Uses correct format "line-filled · bokeh · pyplots.ai" + comment: Correct title format, appropriate axis labels, no legend (single-series) data_quality: - score: 18 - max: 20 + score: 14 + max: 15 items: - id: DQ-01 name: Feature Coverage - score: 7 - max: 8 + score: 5 + max: 6 passed: true - comment: Shows seasonal variation and trend well, demonstrates magnitude emphasis + comment: Shows seasonal variation, growth trend, realistic website traffic + visualization - id: DQ-02 name: Realistic Context - score: 7 - max: 7 + score: 5 + max: 5 passed: true - comment: Website traffic is a realistic, neutral business scenario + comment: Website traffic is plausible context with realistic seasonal pattern + (summer/holiday peaks) - id: DQ-03 name: Appropriate Scale score: 4 - max: 5 + max: 4 passed: true - comment: Values are plausible for website traffic, though seasonal amplitude - is slightly exaggerated + comment: Y-range (0–80k) and X-range (12 months) sensible for domain code_quality: score: 10 max: 10 @@ -165,41 +175,64 @@ review: score: 3 max: 3 passed: true - comment: 'Clean sequential structure: imports → data → plot → save' + comment: Simple, straightforward implementation without unnecessary complexity - id: CQ-02 name: Reproducibility - score: 3 - max: 3 + score: 2 + max: 2 passed: true - comment: Uses np.random.seed(42) + comment: Uses np.random.seed(42) for deterministic output - id: CQ-03 name: Clean Imports score: 2 max: 2 passed: true - comment: All imports are used + comment: All imports used, no clutter or unused modules - id: CQ-04 - name: No Deprecated API - score: 1 - max: 1 + name: Code Elegance + score: 2 + max: 2 passed: true - comment: Uses current Bokeh API + comment: Appropriate complexity, no fake UI or simulated interactivity - id: CQ-05 - name: Output Correct + name: Output & API score: 1 max: 1 passed: true - comment: Saves as plot.png and plot.html - library_features: - score: 2 - max: 5 + comment: Saves PNG and HTML with correct names (plot-light/dark), current + API + library_mastery: + score: 8 + max: 10 items: - - id: LF-01 - name: Uses distinctive library features - score: 2 + - id: LM-01 + name: Idiomatic Usage + score: 5 max: 5 passed: true - comment: Uses ColumnDataSource and HoverTool for interactivity, varea for - fill; could leverage more Bokeh-specific features like CustomJS callbacks - or more advanced tooltips + comment: Excellent use of ColumnDataSource, varea/line/scatter methods, HoverTool, + theme tokens, Selenium PNG export + - id: LM-02 + name: Distinctive Features + score: 3 + max: 5 + passed: true + comment: Good bokeh-specific patterns (varea for fills, HoverTool interactivity, + ColumnDataSource best practice) + score_caps: + applied: false + notes: No cap conditions triggered; all criteria strong verdict: APPROVED +impl_tags: + dependencies: + - selenium + techniques: + - hover-tooltips + - html-export + patterns: + - data-generation + - columndatasource + dataprep: [] + styling: + - alpha-blending + - grid-styling