From 9bc3027c9f58385c980677c49699f1acc25012ea Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 30 Jun 2026 22:49:37 +0000 Subject: [PATCH 1/5] feat(bokeh): implement dumbbell-basic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Regen from quality 88. Addressed: - Canvas size: fixed 4800×2700 → canonical 3200×1800 with CDP viewport override - Title format: added python language token, removed "Employee Satisfaction" prefix - Save method: replaced export_png with Selenium + CDP Emulation.setDeviceMetricsOverride - Typography: updated to canonical 50pt/42pt/34pt sizes for 3200×1800 canvas - Y-axis spine: removed (p.yaxis.axis_line_color = None) for cleaner look - Segment color-coding: segments now green for improvement, red (#AE3030) for regression - Comment hygiene: "Okabe-Ito" → "Imprint palette" - Added sys.path self-shadowing fix (bokeh.py naming conflict) --- .../implementations/python/bokeh.py | 116 +++++++++++++----- 1 file changed, 82 insertions(+), 34 deletions(-) diff --git a/plots/dumbbell-basic/implementations/python/bokeh.py b/plots/dumbbell-basic/implementations/python/bokeh.py index adeb65625e..e24373e702 100644 --- a/plots/dumbbell-basic/implementations/python/bokeh.py +++ b/plots/dumbbell-basic/implementations/python/bokeh.py @@ -1,14 +1,25 @@ -""" anyplot.ai +"""anyplot.ai dumbbell-basic: Basic Dumbbell Chart -Library: bokeh 3.9.0 | Python 3.14.4 -Quality: 88/100 | Updated: 2026-04-26 +Library: bokeh | Python 3.13 +Quality: 88/100 | Updated: 2026-06-30 """ import os +import sys +import time +from pathlib import Path -from bokeh.io import export_png, output_file, save + +# Remove script's own directory from sys.path to prevent self-shadowing +# (this file is named bokeh.py; without this, `import bokeh` would find itself) +_here = os.path.dirname(os.path.abspath(__file__)) +sys.path = [p for p in sys.path if os.path.abspath(p or ".") != _here] + +from bokeh.io import output_file, save from bokeh.models import ColumnDataSource, HoverTool from bokeh.plotting import figure +from selenium import webdriver +from selenium.webdriver.chrome.options import Options # Theme tokens @@ -17,11 +28,10 @@ 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" # Okabe-Ito 1 — "Before" -ACCENT = "#C475FD" # Okabe-Ito 2 — "After" +BRAND = "#009E73" # Imprint palette position 1 — "Before" dots +ACCENT = "#C475FD" # Imprint palette position 2 — "After" dots # Data — Employee satisfaction scores before and after policy changes -# (one department regressed, the rest improved by varying amounts) categories = [ "Engineering", "Marketing", @@ -44,70 +54,81 @@ deltas = [d[3] for d in ordered] # Plot +TITLE = "dumbbell-basic · python · bokeh · anyplot.ai" p = figure( - width=4800, - height=2700, + width=3200, + height=1800, y_range=categories, x_range=(45, 95), - title="Employee Satisfaction · dumbbell-basic · bokeh · anyplot.ai", + title=TITLE, x_axis_label="Satisfaction Score", y_axis_label="Department", background_fill_color=PAGE_BG, border_fill_color=PAGE_BG, toolbar_location=None, + min_border_bottom=160, + min_border_left=280, + min_border_top=110, + min_border_right=60, ) -# Connecting segments — thin, subtle, behind the dots +# Connecting segments — color-coded by direction: green = improvement, red = regression seg_source = ColumnDataSource( - data={"y": categories, "x_start": start_values, "x_end": end_values, "delta": [f"{d:+d}" for d in deltas]} + data={ + "y": categories, + "x_start": start_values, + "x_end": end_values, + "delta": [f"{d:+d}" for d in deltas], + "seg_color": [BRAND if d > 0 else "#AE3030" for d in deltas], + } ) p.segment( - x0="x_start", x1="x_end", y0="y", y1="y", source=seg_source, line_color=INK_SOFT, line_alpha=0.45, line_width=4 + x0="x_start", x1="x_end", y0="y", y1="y", source=seg_source, line_color="seg_color", line_alpha=0.55, line_width=6 ) -# "Before" dots — Okabe-Ito brand green +# "Before" dots — Imprint palette position 1 (brand green) before_source = ColumnDataSource(data={"x": start_values, "y": categories, "phase": ["Before"] * len(categories)}) before_glyph = p.scatter( x="x", y="y", source=before_source, - size=34, + size=28, fill_color=BRAND, line_color=PAGE_BG, - line_width=2, + line_width=3, legend_label="Before policy changes", ) -# "After" dots — Okabe-Ito vermillion +# "After" dots — Imprint palette position 2 (lavender) after_source = ColumnDataSource(data={"x": end_values, "y": categories, "phase": ["After"] * len(categories)}) after_glyph = p.scatter( x="x", y="y", source=after_source, - size=34, + size=28, fill_color=ACCENT, line_color=PAGE_BG, - line_width=2, + line_width=3, legend_label="After policy changes", ) -# Hover tooltip (HTML interactivity) +# Hover tooltip (Bokeh-distinctive interactive feature) p.add_tools( HoverTool( renderers=[before_glyph, after_glyph], tooltips=[("Department", "@y"), ("Phase", "@phase"), ("Score", "@x")] ) ) -# Typography -p.title.text_font_size = "36pt" +# Typography — canonical sizes for 3200×1800 per bokeh.md +p.title.text_font_size = "50pt" p.title.text_color = INK p.title.text_font_style = "normal" p.title.align = "center" -p.xaxis.axis_label_text_font_size = "24pt" -p.yaxis.axis_label_text_font_size = "24pt" -p.xaxis.major_label_text_font_size = "20pt" -p.yaxis.major_label_text_font_size = "20pt" +p.xaxis.axis_label_text_font_size = "42pt" +p.yaxis.axis_label_text_font_size = "42pt" +p.xaxis.major_label_text_font_size = "34pt" +p.yaxis.major_label_text_font_size = "34pt" p.xaxis.axis_label_text_color = INK p.yaxis.axis_label_text_color = INK p.xaxis.major_label_text_color = INK_SOFT @@ -115,12 +136,12 @@ p.xaxis.axis_label_standoff = 18 p.yaxis.axis_label_standoff = 18 -# Spines and ticks — keep an L-shape, suppress chart outline +# Spines — keep x-axis, remove y-axis for a cleaner look p.outline_line_color = None p.xaxis.axis_line_color = INK_SOFT -p.yaxis.axis_line_color = INK_SOFT +p.yaxis.axis_line_color = None p.xaxis.major_tick_line_color = INK_SOFT -p.yaxis.major_tick_line_color = INK_SOFT +p.yaxis.major_tick_line_color = None p.xaxis.minor_tick_line_color = None p.yaxis.minor_tick_line_color = None @@ -129,19 +150,46 @@ p.xgrid.grid_line_alpha = 0.10 p.ygrid.grid_line_color = None -# Legend — placed inside top-left so it never collides with the data range +# Legend p.legend.location = "top_left" p.legend.background_fill_color = ELEVATED_BG p.legend.background_fill_alpha = 0.95 p.legend.border_line_color = INK_SOFT p.legend.border_line_alpha = 0.4 p.legend.label_text_color = INK_SOFT -p.legend.label_text_font_size = "20pt" +p.legend.label_text_font_size = "34pt" p.legend.spacing = 10 p.legend.padding = 18 p.legend.margin = 24 -# Save -export_png(p, filename=f"plot-{THEME}.png") -output_file(f"plot-{THEME}.html", title="Employee Satisfaction · dumbbell-basic · bokeh · anyplot.ai") +# Save interactive HTML (required catalog artifact) +html_path = Path(f"plot-{THEME}.html") +output_file(str(html_path), title=TITLE) save(p) + +# Inject body background CSS to prevent thin border artifact in headless-Chrome screenshot +html_content = html_path.read_text() +body_style = f"" +html_content = html_content.replace("", f"{body_style}\n", 1) +html_path.write_text(html_content) + +# Screenshot via headless Chrome — use CDP to set exact viewport to match figure dimensions +W, H = 3200, 1800 +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) +driver = webdriver.Chrome(options=opts) +driver.execute_cdp_cmd( + "Emulation.setDeviceMetricsOverride", {"width": W, "height": H, "deviceScaleFactor": 1, "mobile": False} +) +driver.get(f"file://{html_path.resolve()}") +time.sleep(3) +driver.save_screenshot(f"plot-{THEME}.png") +driver.quit() From d13d65d2ed324463d1f3206f3a843e3e8a0ded75 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 30 Jun 2026 22:49:49 +0000 Subject: [PATCH 2/5] chore(bokeh): add metadata for dumbbell-basic --- .../dumbbell-basic/metadata/python/bokeh.yaml | 247 +----------------- 1 file changed, 11 insertions(+), 236 deletions(-) diff --git a/plots/dumbbell-basic/metadata/python/bokeh.yaml b/plots/dumbbell-basic/metadata/python/bokeh.yaml index 2e4b5c7080..6b17804107 100644 --- a/plots/dumbbell-basic/metadata/python/bokeh.yaml +++ b/plots/dumbbell-basic/metadata/python/bokeh.yaml @@ -1,246 +1,21 @@ +# Per-library metadata for bokeh implementation of dumbbell-basic +# Auto-generated by impl-generate.yml + library: bokeh language: python specification_id: dumbbell-basic created: '2025-12-23T13:02:56Z' -updated: '2026-04-26T01:29:49Z' -generated_by: claude-opus -workflow_run: 24945052285 +updated: '2026-06-30T22:49:49Z' +generated_by: claude-sonnet +workflow_run: 28480554709 issue: 945 -python_version: 3.14.4 -library_version: 3.9.0 +language_version: 3.13.14 +library_version: 3.9.1 preview_url_light: https://storage.googleapis.com/anyplot-images/plots/dumbbell-basic/python/bokeh/plot-light.png preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/dumbbell-basic/python/bokeh/plot-dark.png preview_html_light: https://storage.googleapis.com/anyplot-images/plots/dumbbell-basic/python/bokeh/plot-light.html preview_html_dark: https://storage.googleapis.com/anyplot-images/plots/dumbbell-basic/python/bokeh/plot-dark.html -quality_score: 88 +quality_score: null review: - strengths: - - 'Perfect palette compliance: #009E73 before, #D55E00 after, warm off-white/near-black - backgrounds, chrome fully adaptive across both themes with no dark-on-dark failures.' - - 'Excellent data design: sorted by delta ascending, one regression (Finance −6) - at bottom and largest improvement (R&D +23) at top — viewer reads the story immediately - without annotations.' - - 'Perfect code quality: clean linear structure, all imports used, idiomatic Bokeh - with ColumnDataSource, HoverTool tooltips, and HTML export alongside PNG.' - - HoverTool and HTML export are genuinely Bokeh-distinctive features that elevate - the implementation above a static equivalent. - weaknesses: - - 'Title format deviates from required spec: ''Employee Satisfaction · dumbbell-basic - · bokeh · anyplot.ai'' should be ''dumbbell-basic · bokeh · anyplot.ai''.' - - 'Design Excellence gap (13/20): needs higher aesthetic sophistication — directional - arrow tips on connecting segments (Bokeh Arrow with VeeHead) or segment color-coding - by improvement vs. regression would elevate DE-01 above 5/8.' - - Y-axis spine still visible; removing it (p.yaxis.axis_line_color = None) and slightly - tightening row spacing would push DE-02 above 4/6. - image_description: |- - Light render (plot-light.png): - Background: Warm off-white, consistent with #FAF8F1 — not pure white, not dark. - Chrome: Title "Employee Satisfaction · dumbbell-basic · bokeh · anyplot.ai" in dark ink at top-center. Y-axis label "Department" rotated, dark ink. X-axis label "Satisfaction Score" in dark ink. Y-axis category labels (Research & Development, Human Resources, Marketing, Engineering, Customer Support, Operations, Sales, Finance) in INK_SOFT. X-axis tick labels (50, 60, 70, 80, 90) in INK_SOFT. All readable. - Data: 8 horizontal dumbbell rows. Before-dots in #009E73 (brand green, Okabe-Ito position 1). After-dots in #D55E00 (vermillion, Okabe-Ito position 2). Thin gray connecting segments with alpha=0.45. Sorted ascending by delta: Finance (−6 regression) at bottom, R&D (+23 improvement) at top. Subtle vertical grid lines at alpha=0.10. Legend top-left with elevated background. - Legibility verdict: PASS — all text clearly readable against light background. - - Dark render (plot-dark.png): - Background: Warm near-black, consistent with #1A1A17 — not pure black, not light. - Chrome: Title, axis labels, tick labels, and legend text all render in light ink (#F0EFE8 / #B8B7B0). No dark-on-dark failures detected. Legend uses elevated dark fill (#242420). Y-axis spine and x-axis spine visible in INK_SOFT. Grid lines subtle. - Data: Data colors identical to light render — #009E73 before-dots and #D55E00 after-dots unchanged. Only chrome (background, text, grid, legend frame) flips between themes. - Legibility verdict: PASS — all text clearly readable against dark background; no "dark on dark" failures. - criteria_checklist: - visual_quality: - score: 29 - max: 30 - items: - - id: VQ-01 - name: Text Legibility - score: 8 - max: 8 - passed: true - comment: 'All sizes explicitly set above minimums: title 36pt, axis labels - 24pt, tick/legend labels 20pt. Both renders fully readable.' - - id: VQ-02 - name: No Overlap - score: 6 - max: 6 - passed: true - comment: No overlapping elements in either render. - - id: VQ-03 - name: Element Visibility - score: 6 - max: 6 - passed: true - comment: size=34 dots clearly visible for 8 categories; thin connecting lines - intentional per spec. - - id: VQ-04 - name: Color Accessibility - score: 2 - max: 2 - passed: true - comment: '#009E73 / #D55E00 are Okabe-Ito positions 1-2; CVD-safe and sufficient - luminance contrast.' - - id: VQ-05 - name: Layout & Canvas - score: 3 - max: 4 - passed: true - comment: Good canvas use; generous vertical spacing between 8 rows leaves - some whitespace. - - id: VQ-06 - name: Axis Labels & Title - score: 2 - max: 2 - passed: true - comment: '''Satisfaction Score'' and ''Department'' are descriptive.' - - id: VQ-07 - name: Palette Compliance - score: 2 - max: 2 - passed: true - comment: 'First series #009E73, second #D55E00, backgrounds #FAF8F1/#1A1A17, - chrome fully adaptive in both renders.' - design_excellence: - score: 13 - max: 20 - items: - - id: DE-01 - name: Aesthetic Sophistication - score: 5 - max: 8 - passed: true - comment: 'Above plain default: thoughtful sorting, clean legend, no outline. - Doesn''t reach publication level — no directional indicators or color-by-magnitude.' - - id: DE-02 - name: Visual Refinement - score: 4 - max: 6 - passed: true - comment: Outline removed, vertical-only grid at alpha=0.10, minor ticks suppressed, - elevated legend. Y-axis spine still present; row spacing could be tighter. - - id: DE-03 - name: Data Storytelling - score: 4 - max: 6 - passed: true - comment: 'Sorting by delta creates clear visual hierarchy: R&D +23 at top, - Finance −6 regression at bottom tells the story immediately.' - spec_compliance: - score: 14 - max: 15 - items: - - id: SC-01 - name: Plot Type - score: 5 - max: 5 - passed: true - comment: Correct horizontal dumbbell/connected dot plot. - - id: SC-02 - name: Required Features - score: 4 - max: 4 - passed: true - comment: Two distinct-color dots per category, connected by thin subtle line, - horizontal orientation, categories on y-axis, 8 categories within 5-20 range. - - id: SC-03 - name: Data Mapping - score: 3 - max: 3 - passed: true - comment: Categories on y-axis, satisfaction scores on x-axis, all data visible. - - id: SC-04 - name: Title & Legend - score: 2 - max: 3 - passed: false - comment: 'Title has extra prefix ''Employee Satisfaction · '' before spec-id. - Required: ''dumbbell-basic · bokeh · anyplot.ai''. Legend labels correct.' - data_quality: - score: 15 - max: 15 - items: - - id: DQ-01 - name: Feature Coverage - score: 6 - max: 6 - passed: true - comment: Mix of large improvements (+23 R&D), small improvements (+11 Sales), - and one regression (−6 Finance); varied before-values 55-78 and after-values - 70-88. - - id: DQ-02 - name: Realistic Context - score: 5 - max: 5 - passed: true - comment: Employee satisfaction by department before/after policy changes — - real, comprehensible, neutral business scenario. - - id: DQ-03 - name: Appropriate Scale - score: 4 - max: 4 - passed: true - comment: Scores 55-88 on 0-100 scale; change magnitudes −6 to +23 realistic - for policy interventions. - code_quality: - score: 10 - max: 10 - items: - - id: CQ-01 - name: KISS Structure - score: 3 - max: 3 - passed: true - comment: 'Linear: imports → tokens → data → figure → glyphs → styling → save. - No functions or classes.' - - id: CQ-02 - name: Reproducibility - score: 2 - max: 2 - passed: true - comment: Fully deterministic hardcoded arrays; no random seed needed. - - id: CQ-03 - name: Clean Imports - score: 2 - max: 2 - passed: true - comment: All four imports (os, bokeh.io, bokeh.models, bokeh.plotting) are - used. - - id: CQ-04 - name: Code Elegance - score: 2 - max: 2 - passed: true - comment: Clean, Pythonic. Appropriate complexity for a dumbbell chart. - - id: CQ-05 - name: Output & API - score: 1 - max: 1 - passed: true - comment: Saves plot-{THEME}.png and plot-{THEME}.html using current Bokeh - API. - library_mastery: - score: 7 - max: 10 - items: - - id: LM-01 - name: Idiomatic Usage - score: 4 - max: 5 - passed: true - comment: y_range=categories for categorical axis, separate ColumnDataSources - per series, segment() + scatter() pattern. Solid Bokeh idiom. - - id: LM-02 - name: Distinctive Features - score: 3 - max: 5 - passed: true - comment: HoverTool with @y/@phase/@x tooltips and HTML export are Bokeh-distinctive; - no other library generates interactive .html as primary output alongside - PNG. - verdict: REJECTED -impl_tags: - dependencies: [] - techniques: - - hover-tooltips - - html-export - patterns: - - columndatasource - dataprep: [] - styling: - - alpha-blending + strengths: [] + weaknesses: [] From bf7f1912d9dc439324dfa6d71994bbc6e81a0cb6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 30 Jun 2026 23:00:14 +0000 Subject: [PATCH 3/5] chore(bokeh): update quality score 88 and review feedback for dumbbell-basic --- .../implementations/python/bokeh.py | 4 +- .../dumbbell-basic/metadata/python/bokeh.yaml | 275 +++++++++++++++++- 2 files changed, 270 insertions(+), 9 deletions(-) diff --git a/plots/dumbbell-basic/implementations/python/bokeh.py b/plots/dumbbell-basic/implementations/python/bokeh.py index e24373e702..7be3fb2f15 100644 --- a/plots/dumbbell-basic/implementations/python/bokeh.py +++ b/plots/dumbbell-basic/implementations/python/bokeh.py @@ -1,6 +1,6 @@ -"""anyplot.ai +""" anyplot.ai dumbbell-basic: Basic Dumbbell Chart -Library: bokeh | Python 3.13 +Library: bokeh 3.9.1 | Python 3.13.14 Quality: 88/100 | Updated: 2026-06-30 """ diff --git a/plots/dumbbell-basic/metadata/python/bokeh.yaml b/plots/dumbbell-basic/metadata/python/bokeh.yaml index 6b17804107..775570a064 100644 --- a/plots/dumbbell-basic/metadata/python/bokeh.yaml +++ b/plots/dumbbell-basic/metadata/python/bokeh.yaml @@ -1,11 +1,8 @@ -# Per-library metadata for bokeh implementation of dumbbell-basic -# Auto-generated by impl-generate.yml - library: bokeh language: python specification_id: dumbbell-basic created: '2025-12-23T13:02:56Z' -updated: '2026-06-30T22:49:49Z' +updated: '2026-06-30T23:00:14Z' generated_by: claude-sonnet workflow_run: 28480554709 issue: 945 @@ -15,7 +12,271 @@ preview_url_light: https://storage.googleapis.com/anyplot-images/plots/dumbbell- preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/dumbbell-basic/python/bokeh/plot-dark.png preview_html_light: https://storage.googleapis.com/anyplot-images/plots/dumbbell-basic/python/bokeh/plot-light.html preview_html_dark: https://storage.googleapis.com/anyplot-images/plots/dumbbell-basic/python/bokeh/plot-dark.html -quality_score: null +quality_score: 88 review: - strengths: [] - weaknesses: [] + strengths: + - Correct dumbbell chart with horizontal orientation and categories on y-axis, fully + matching the spec + - Color-coded connecting segments (brand green for improvement, matte red for Finance + regression) adds semantic meaning beyond a generic connecting line + - Sorted by delta ascending (largest improvement at top) creates natural visual + storytelling with Finance regression as a clear outlier + - 'Correct Imprint palette: Before dots use #009E73 (position 1), After dots use + #C475FD (position 2), regression segment uses #AE3030 (semantic red)' + - 'Effective Bokeh-distinctive features: HoverTool with custom tooltips, interactive + HTML output alongside PNG' + - Theme adaptation is excellent — all chrome elements (title, labels, ticks, legend + text, backgrounds) correctly adapt between light and dark renders + - White dot outlines (line_color=PAGE_BG) add definition and prevent dots from blending + with the background + - Clean, deterministic code with KISS structure; self-shadowing workaround for bokeh.py + filename is correctly applied + weaknesses: + - 'DE-01 (4/8): Design is above defaults but not yet publication-quality — overall + aesthetic is a well-configured library default; consider more refined typography + treatment or visual polish' + - 'DE-03 (3/6): Finance regression is highlighted by color but the story is implicit; + delta labels on connecting segments (e.g., +16, +17, -6) or a subtitle would make + the narrative explicit' + - 'LM-02 (3/5): HoverTool and HTML output are distinctive, but implementation is + relatively standard Bokeh — could leverage Bokeh tap/select tools, shared hover + across Before/After glyphs, or custom hover template with delta calculation' + - 'VQ-05 (3/4): Legend at top_left is placed inside the data area and slightly crowds + the Research & Development row at the top; consider bottom_left placement or legend + outside the plot area to the right' + - 'VQ-01 (7/8): The y-axis label ''Department'' is a short word at 42pt — slightly + disproportionate relative to its information content; consider 36pt for better + proportional balance with the data' + image_description: |- + Light render (plot-light.png): + Background: Warm off-white (#FAF8F1) — correct, not pure white. + Chrome: Title "dumbbell-basic · python · bokeh · anyplot.ai" in dark ink (#1A1A17), clearly legible, fills ~75% of canvas width (expected for this title length). X-axis label "Satisfaction Score" in dark ink, y-axis label "Department" rotated, also dark. Tick labels in soft dark (#4A4A44). All text clearly readable against the warm off-white background. + Data: 8 departments on y-axis. "Before" dots in brand green (#009E73), "After" dots in lavender (#C475FD). Connecting segments in brand green for improvements and matte red (#AE3030) for Finance (only regression). Finance row (bottom) shows green Before dot at x=78 (right) and lavender After dot at x=72 (left) with a red segment — correctly representing a regression. Legend at top_left with warm elevated background (#FFFDF6) shows "Before policy changes" and "After policy changes". Subtle vertical grid lines at 10% alpha. + Legibility verdict: PASS — all text readable, dot sizes (28) prominent for 8 sparse data points. + + Dark render (plot-dark.png): + Background: Warm near-black (#1A1A17) — correct, not pure black. + Chrome: Title in light cream (#F0EFE8), clearly legible against dark background. Axis labels and tick labels in soft light (#B8B7B0). Legend box has dark elevated background (#242420) with light border and light label text. No dark-on-dark failures observed — all text elements are light-colored and clearly visible against the near-black surface. + Data: Data colors are identical to the light render — brand green (#009E73) for Before dots, lavender (#C475FD) for After dots, matte red segment for Finance regression. Imprint palette colors unchanged between themes (only chrome flips). Both dot colors remain visually distinct and prominent in the dark theme. + Legibility verdict: PASS — all text readable, no dark-on-dark failures, data elements clearly visible against dark background. + criteria_checklist: + visual_quality: + score: 28 + max: 30 + items: + - id: VQ-01 + name: Text Legibility + score: 7 + max: 8 + passed: true + comment: 'All font sizes explicitly set (50pt title, 42pt axis labels, 34pt + ticks/legend). Well-proportioned in both themes. Minor: ''Department'' y-axis + label at 42pt is slightly large for a short word — proportional sizing check + notes short labels should not dominate with oversized fontsizes.' + - id: VQ-02 + name: No Overlap + score: 6 + max: 6 + passed: true + comment: No overlap. Legend at top_left is close to the R&D Before dot but + does not obscure it. Category labels are well-spaced. No tick label collision. + - id: VQ-03 + name: Element Visibility + score: 6 + max: 6 + passed: true + comment: Dots at size=28 are prominent for 8 sparse data points. Connecting + segments at line_width=6 clearly visible. White dot outlines add definition. + - id: VQ-04 + name: Color Accessibility + score: 2 + max: 2 + passed: true + comment: Imprint palette (green + lavender) with semantic red for regression. + White dot outlines improve contrast. Both colors distinct under CVD simulation. + - id: VQ-05 + name: Layout & Canvas + score: 3 + max: 4 + passed: true + comment: Good proportions and canvas utilization. Legend at top_left is inside + the data area and slightly crowds the Research & Development row at the + top — minor layout issue. + - id: VQ-06 + name: Axis Labels & Title + score: 2 + max: 2 + passed: true + comment: Title format correct. 'Satisfaction Score' is descriptive; scores + are unitless so no unit suffix needed. 'Department' is appropriate. + - id: VQ-07 + name: Palette Compliance + score: 2 + max: 2 + passed: true + comment: 'Before dots (#009E73, Imprint pos 1) correct as first series. After + dots (#C475FD, Imprint pos 2) correct. Regression segment uses #AE3030 (semantic + matte red — appropriate for regression/loss). Backgrounds #FAF8F1 light + / #1A1A17 dark correct. Chrome adapts correctly in both renders.' + design_excellence: + score: 12 + max: 20 + items: + - id: DE-01 + name: Aesthetic Sophistication + score: 5 + max: 8 + passed: true + comment: Above defaults. Color-coded segments by improvement/regression direction + is a genuine design choice adding semantic value. Dot outlines and minimal + chrome contribute. Not yet 'FiveThirtyEight-level' publication quality. + - id: DE-02 + name: Visual Refinement + score: 4 + max: 6 + passed: true + comment: 'Good refinement: y-axis spine removed, only x-axis kept, subtle + vertical grid at 10% alpha, generous explicit margins, no Y ticks. Clearly + above minimal-customization level.' + - id: DE-03 + name: Data Storytelling + score: 3 + max: 6 + passed: true + comment: Sorting by delta (ascending) with Finance regression at bottom creates + implicit hierarchy. Red segment highlights the lone regression case. Story + is visible but implicit — no delta labels on segments, no subtitle, viewer + must read the chart to find the Finance outlier. + spec_compliance: + score: 15 + max: 15 + items: + - id: SC-01 + name: Plot Type + score: 5 + max: 5 + passed: true + comment: 'Correct dumbbell chart: two dots per category connected by a line, + horizontal orientation, categories on y-axis.' + - id: SC-02 + name: Required Features + score: 4 + max: 4 + passed: true + comment: 'All spec features present: two distinct dot colors, connecting line, + horizontal orientation, sorted by difference, 5-20 categories (8 used).' + - id: SC-03 + name: Data Mapping + score: 3 + max: 3 + passed: true + comment: Categories on y-axis, satisfaction scores on x-axis. Before mapped + to first series (green), After to second series (lavender). All data visible. + - id: SC-04 + name: Title & Legend + score: 3 + max: 3 + passed: true + comment: Title 'dumbbell-basic · python · bokeh · anyplot.ai' correct format. + Legend labels 'Before policy changes' / 'After policy changes' match data + context. + data_quality: + score: 15 + max: 15 + items: + - id: DQ-01 + name: Feature Coverage + score: 6 + max: 6 + passed: true + comment: Shows both improvement (7 departments) and regression (Finance, -6 + pts) cases. Sorted by delta to reveal patterns. Covers the full feature + range of a dumbbell chart. + - id: DQ-02 + name: Realistic Context + score: 5 + max: 5 + passed: true + comment: Employee satisfaction scores before/after policy changes — real-world + HR scenario, neutral business domain, plausible department names. + - id: DQ-03 + name: Appropriate Scale + score: 4 + max: 4 + passed: true + comment: Scores in range 55-88 on a presumed 0-100 scale. Improvements up + to 23 points are plausible. One regression (-6) is realistic. Values are + internally consistent. + code_quality: + score: 10 + max: 10 + items: + - id: CQ-01 + name: KISS Structure + score: 3 + max: 3 + passed: true + comment: 'Linear: self-path fix → imports → constants → data → sort → plot + → save. No functions or classes.' + - id: CQ-02 + name: Reproducibility + score: 2 + max: 2 + passed: true + comment: Hardcoded data — fully deterministic, no randomness. + - id: CQ-03 + name: Clean Imports + score: 2 + max: 2 + passed: true + comment: 'All imports used: os/sys/time/pathlib for system ops, bokeh.io/models/plotting + for chart, selenium for screenshot.' + - id: CQ-04 + name: Code Elegance + score: 2 + max: 2 + passed: true + comment: Clean implementation, no over-engineering. Self-shadowing workaround + is necessary for a file named bokeh.py. List comprehensions are clean. + - id: CQ-05 + name: Output & API + score: 1 + max: 1 + passed: true + comment: Saves plot-{THEME}.png (via Selenium) and plot-{THEME}.html (via + output_file/save). Correct for an interactive library. + library_mastery: + score: 8 + max: 10 + items: + - id: LM-01 + name: Idiomatic Usage + score: 5 + max: 5 + passed: true + comment: ColumnDataSource throughout, HoverTool, output_file/save, theme-adaptive + environment variable pattern, segment() for connecting lines — all idiomatic + Bokeh. + - id: LM-02 + name: Distinctive Features + score: 3 + max: 5 + passed: true + comment: HoverTool (Bokeh-distinctive interactive feature) and HTML interactive + output are genuinely distinctive. ColumnDataSource with mapped colors per + segment is convenient Bokeh usage. Implementation is solid but fairly standard + — could leverage shared hover across Before/After renderers or custom hover + template showing delta. + verdict: REJECTED +impl_tags: + dependencies: + - selenium + techniques: + - hover-tooltips + - html-export + patterns: + - columndatasource + dataprep: [] + styling: + - alpha-blending + - edge-highlighting From 88446aaed40b3465310eb8ab3ef2eb25a4d88536 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 30 Jun 2026 23:05:27 +0000 Subject: [PATCH 4/5] fix(bokeh): address review feedback for dumbbell-basic Attempt 1/3 - fixes based on AI review --- .../implementations/python/bokeh.py | 55 ++++++++++++++++--- 1 file changed, 47 insertions(+), 8 deletions(-) diff --git a/plots/dumbbell-basic/implementations/python/bokeh.py b/plots/dumbbell-basic/implementations/python/bokeh.py index 7be3fb2f15..651903ae39 100644 --- a/plots/dumbbell-basic/implementations/python/bokeh.py +++ b/plots/dumbbell-basic/implementations/python/bokeh.py @@ -1,4 +1,4 @@ -""" anyplot.ai +"""anyplot.ai dumbbell-basic: Basic Dumbbell Chart Library: bokeh 3.9.1 | Python 3.13.14 Quality: 88/100 | Updated: 2026-06-30 @@ -16,7 +16,7 @@ sys.path = [p for p in sys.path if os.path.abspath(p or ".") != _here] from bokeh.io import output_file, save -from bokeh.models import ColumnDataSource, HoverTool +from bokeh.models import ColumnDataSource, HoverTool, LabelSet from bokeh.plotting import figure from selenium import webdriver from selenium.webdriver.chrome.options import Options @@ -86,8 +86,38 @@ x0="x_start", x1="x_end", y0="y", y1="y", source=seg_source, line_color="seg_color", line_alpha=0.55, line_width=6 ) +# Delta labels on connecting segments — makes improvement/regression story explicit +label_source = ColumnDataSource( + data={ + "x": [(s + e) / 2 for s, e in zip(start_values, end_values, strict=True)], + "y": categories, + "text": [f"{d:+d}" for d in deltas], + } +) +p.add_layout( + LabelSet( + x="x", + y="y", + text="text", + source=label_source, + text_align="center", + text_baseline="bottom", + text_font_size="26pt", + text_color=INK_SOFT, + y_offset=24, + ) +) + # "Before" dots — Imprint palette position 1 (brand green) -before_source = ColumnDataSource(data={"x": start_values, "y": categories, "phase": ["Before"] * len(categories)}) +before_source = ColumnDataSource( + data={ + "x": start_values, + "y": categories, + "phase": ["Before"] * len(categories), + "after": end_values, + "delta": [f"{d:+d} pts" for d in deltas], + } +) before_glyph = p.scatter( x="x", y="y", @@ -100,7 +130,15 @@ ) # "After" dots — Imprint palette position 2 (lavender) -after_source = ColumnDataSource(data={"x": end_values, "y": categories, "phase": ["After"] * len(categories)}) +after_source = ColumnDataSource( + data={ + "x": end_values, + "y": categories, + "phase": ["After"] * len(categories), + "before": start_values, + "delta": [f"{d:+d} pts" for d in deltas], + } +) after_glyph = p.scatter( x="x", y="y", @@ -112,10 +150,11 @@ legend_label="After policy changes", ) -# Hover tooltip (Bokeh-distinctive interactive feature) +# Hover tooltip — shows department, phase, score, and delta change together p.add_tools( HoverTool( - renderers=[before_glyph, after_glyph], tooltips=[("Department", "@y"), ("Phase", "@phase"), ("Score", "@x")] + renderers=[before_glyph, after_glyph], + tooltips=[("Department", "@y"), ("Phase", "@phase"), ("Score", "@x"), ("Δ Change", "@delta")], ) ) @@ -126,7 +165,7 @@ p.title.align = "center" p.xaxis.axis_label_text_font_size = "42pt" -p.yaxis.axis_label_text_font_size = "42pt" +p.yaxis.axis_label_text_font_size = "36pt" p.xaxis.major_label_text_font_size = "34pt" p.yaxis.major_label_text_font_size = "34pt" p.xaxis.axis_label_text_color = INK @@ -151,7 +190,7 @@ p.ygrid.grid_line_color = None # Legend -p.legend.location = "top_left" +p.legend.location = "bottom_left" p.legend.background_fill_color = ELEVATED_BG p.legend.background_fill_alpha = 0.95 p.legend.border_line_color = INK_SOFT From ae9ad3fffc6aa9ea9c2ccb75c43d85cba3c7e2c4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 30 Jun 2026 23:11:27 +0000 Subject: [PATCH 5/5] chore(bokeh): update quality score 88 and review feedback for dumbbell-basic --- .../implementations/python/bokeh.py | 2 +- .../dumbbell-basic/metadata/python/bokeh.yaml | 231 +++++++++--------- 2 files changed, 121 insertions(+), 112 deletions(-) diff --git a/plots/dumbbell-basic/implementations/python/bokeh.py b/plots/dumbbell-basic/implementations/python/bokeh.py index 651903ae39..db8240b132 100644 --- a/plots/dumbbell-basic/implementations/python/bokeh.py +++ b/plots/dumbbell-basic/implementations/python/bokeh.py @@ -1,4 +1,4 @@ -"""anyplot.ai +""" anyplot.ai dumbbell-basic: Basic Dumbbell Chart Library: bokeh 3.9.1 | Python 3.13.14 Quality: 88/100 | Updated: 2026-06-30 diff --git a/plots/dumbbell-basic/metadata/python/bokeh.yaml b/plots/dumbbell-basic/metadata/python/bokeh.yaml index 775570a064..312fe7ccd1 100644 --- a/plots/dumbbell-basic/metadata/python/bokeh.yaml +++ b/plots/dumbbell-basic/metadata/python/bokeh.yaml @@ -2,7 +2,7 @@ library: bokeh language: python specification_id: dumbbell-basic created: '2025-12-23T13:02:56Z' -updated: '2026-06-30T23:00:14Z' +updated: '2026-06-30T23:11:27Z' generated_by: claude-sonnet workflow_run: 28480554709 issue: 945 @@ -15,53 +15,56 @@ preview_html_dark: https://storage.googleapis.com/anyplot-images/plots/dumbbell- quality_score: 88 review: strengths: - - Correct dumbbell chart with horizontal orientation and categories on y-axis, fully - matching the spec - - Color-coded connecting segments (brand green for improvement, matte red for Finance - regression) adds semantic meaning beyond a generic connecting line - - Sorted by delta ascending (largest improvement at top) creates natural visual - storytelling with Finance regression as a clear outlier - - 'Correct Imprint palette: Before dots use #009E73 (position 1), After dots use - #C475FD (position 2), regression segment uses #AE3030 (semantic red)' - - 'Effective Bokeh-distinctive features: HoverTool with custom tooltips, interactive - HTML output alongside PNG' - - Theme adaptation is excellent — all chrome elements (title, labels, ticks, legend - text, backgrounds) correctly adapt between light and dark renders - - White dot outlines (line_color=PAGE_BG) add definition and prevent dots from blending - with the background - - Clean, deterministic code with KISS structure; self-shadowing workaround for bokeh.py - filename is correctly applied + - 'Correct Imprint palette usage: #009E73 (brand green) for ''Before'' and #C475FD + (lavender) for ''After'' dots, with semantic red #AE3030 for the Finance regression + segment' + - Delta labels above each connecting segment make the story immediately explicit + — viewer sees +23, +17, etc. without reading data + - Categories sorted ascending by delta so the largest improvement (R&D +23) sits + at the top — strong visual hierarchy + - Color-coded segments (green for improvements, red for regression) add a redundant + semantic layer that reinforces the direction-of-change narrative + - 'Full theme-adaptive chrome: backgrounds, text, grid, and legend box all flip + correctly between light (#FAF8F1) and dark (#1A1A17) renders' + - White dot edges (line_color=PAGE_BG) give clean separation on both surfaces without + introducing new colors + - LabelSet for delta annotations and HoverTool for interactive tooltip are idiomatic + bokeh; HTML artifact is generated as required catalog artifact + - 8 categories with realistic employee satisfaction data including one regression + (Finance -6) adds narrative depth + - min_border_left=280 is correctly generous to accommodate the long 'Research & + Development' category label without clipping weaknesses: - - 'DE-01 (4/8): Design is above defaults but not yet publication-quality — overall - aesthetic is a well-configured library default; consider more refined typography - treatment or visual polish' - - 'DE-03 (3/6): Finance regression is highlighted by color but the story is implicit; - delta labels on connecting segments (e.g., +16, +17, -6) or a subtitle would make - the narrative explicit' - - 'LM-02 (3/5): HoverTool and HTML output are distinctive, but implementation is - relatively standard Bokeh — could leverage Bokeh tap/select tools, shared hover - across Before/After glyphs, or custom hover template with delta calculation' - - 'VQ-05 (3/4): Legend at top_left is placed inside the data area and slightly crowds - the Research & Development row at the top; consider bottom_left placement or legend - outside the plot area to the right' - - 'VQ-01 (7/8): The y-axis label ''Department'' is a short word at 42pt — slightly - disproportionate relative to its information content; consider 36pt for better - proportional balance with the data' + - 'Legend placement `p.legend.location = ''bottom_left''` places the legend box + directly over the Finance row (bottom data row after ascending-delta sort), partially + obscuring the Finance dumbbell dots (before=78, after=72) and the ''-6'' delta + label. Fix: move legend to ''top_left'' (where there is more empty space above + the R&D row''s x=65 start dot) or ''bottom_right'' (clear of all dots since all + data is clustered in x=55-90 range but bottom-right is open), or use explicit + offset — e.g. `p.legend.location = ''top_left''` which avoids the data region + entirely.' + - X-axis label 'Satisfaction Score' is set at 42pt while Y-axis label 'Department' + is 36pt — the 6pt gap creates a mild imbalance. Per style guide, axis labels should + be visually similar in size. Align y-axis to 42pt as well (the min_border_left=280 + already reserves room for this). image_description: |- Light render (plot-light.png): - Background: Warm off-white (#FAF8F1) — correct, not pure white. - Chrome: Title "dumbbell-basic · python · bokeh · anyplot.ai" in dark ink (#1A1A17), clearly legible, fills ~75% of canvas width (expected for this title length). X-axis label "Satisfaction Score" in dark ink, y-axis label "Department" rotated, also dark. Tick labels in soft dark (#4A4A44). All text clearly readable against the warm off-white background. - Data: 8 departments on y-axis. "Before" dots in brand green (#009E73), "After" dots in lavender (#C475FD). Connecting segments in brand green for improvements and matte red (#AE3030) for Finance (only regression). Finance row (bottom) shows green Before dot at x=78 (right) and lavender After dot at x=72 (left) with a red segment — correctly representing a regression. Legend at top_left with warm elevated background (#FFFDF6) shows "Before policy changes" and "After policy changes". Subtle vertical grid lines at 10% alpha. - Legibility verdict: PASS — all text readable, dot sizes (28) prominent for 8 sparse data points. + Background: Warm off-white #FAF8F1 — correct, no pure white. + Chrome: Title "dumbbell-basic · python · bokeh · anyplot.ai" centered at top in dark ink (#1A1A17) — clear and readable. Y-axis label "Department" (rotated) in dark ink. X-axis label "Satisfaction Score" in italic dark ink. Tick labels in #4A4A44 (INK_SOFT) — all readable. Subtle vertical grid lines at low alpha (0.10). Y-axis spine removed; x-axis spine kept. + Data: Green dots (#009E73) mark "Before" satisfaction scores; lavender dots (#C475FD) mark "After" scores. Connecting segments colored green for improvements and red (#AE3030) for Finance regression. Delta labels (+23, +17, +16, +16, +15, +13, +11, -6) in INK_SOFT above each segment midpoint. 8 departments sorted by ascending delta. Finance at bottom shows -6 regression. + Legend: Positioned bottom-left with ELEVATED_BG fill. Legend overlaps the Finance row (bottom data row), partially obscuring the Finance dumbbell and '-6' label. + First series color: #009E73 ✓ + Legibility verdict: PASS — all chrome text is readable against the off-white background. Minor issue: legend overlaps bottom data row. Dark render (plot-dark.png): - Background: Warm near-black (#1A1A17) — correct, not pure black. - Chrome: Title in light cream (#F0EFE8), clearly legible against dark background. Axis labels and tick labels in soft light (#B8B7B0). Legend box has dark elevated background (#242420) with light border and light label text. No dark-on-dark failures observed — all text elements are light-colored and clearly visible against the near-black surface. - Data: Data colors are identical to the light render — brand green (#009E73) for Before dots, lavender (#C475FD) for After dots, matte red segment for Finance regression. Imprint palette colors unchanged between themes (only chrome flips). Both dot colors remain visually distinct and prominent in the dark theme. - Legibility verdict: PASS — all text readable, no dark-on-dark failures, data elements clearly visible against dark background. + Background: Warm near-black #1A1A17 — correct, not pure black. + Chrome: Title in #F0EFE8 (INK light) — clearly readable against dark surface. Y-axis and X-axis labels in #F0EFE8 — readable. Tick labels in #B8B7B0 (INK_SOFT dark) — readable, no dark-on-dark failure. Delta labels (+23, +17, etc.) in #B8B7B0 — visible against dark background. Grid lines at low alpha — subtle and unobtrusive. + Data: Green (#009E73) and lavender (#C475FD) dots are identical to the light render — palette colors are theme-independent ✓. Red (#AE3030) segment for Finance regression is visible. All data elements clearly distinguishable from the near-black background. + Legend: Elevated dark background (#242420) with light text (#B8B7B0) — readable. Same bottom-left overlap with Finance row as in light render. + Legibility verdict: PASS — no dark-on-dark failures. All text elements use light chrome tokens correctly. Brand green #009E73 is clearly visible against #1A1A17. criteria_checklist: visual_quality: - score: 28 + score: 25 max: 30 items: - id: VQ-01 @@ -69,57 +72,59 @@ review: score: 7 max: 8 passed: true - comment: 'All font sizes explicitly set (50pt title, 42pt axis labels, 34pt - ticks/legend). Well-proportioned in both themes. Minor: ''Department'' y-axis - label at 42pt is slightly large for a short word — proportional sizing check - notes short labels should not dominate with oversized fontsizes.' + comment: 'Font sizes explicitly set (50pt title, 42pt x-axis, 36pt y-axis, + 34pt ticks). Readable in both themes. Minor: y-axis label 36pt vs x-axis + 42pt creates a slight size imbalance.' - id: VQ-02 name: No Overlap - score: 6 + score: 3 max: 6 - passed: true - comment: No overlap. Legend at top_left is close to the R&D Before dot but - does not obscure it. Category labels are well-spaced. No tick label collision. + passed: false + comment: legend.location='bottom_left' places legend box directly over the + Finance row (bottom row after ascending-delta sort), obscuring Finance dumbbell + dots and '-6' delta label in both renders. - id: VQ-03 name: Element Visibility score: 6 max: 6 passed: true - comment: Dots at size=28 are prominent for 8 sparse data points. Connecting - segments at line_width=6 clearly visible. White dot outlines add definition. + comment: Dots at size=28 are prominent for 8 data points. Connecting lines + at line_width=6 with alpha=0.55 are visible. Delta labels at 26pt are clear. + All data elements well-sized for data density. - id: VQ-04 name: Color Accessibility score: 2 max: 2 passed: true - comment: Imprint palette (green + lavender) with semantic red for regression. - White dot outlines improve contrast. Both colors distinct under CVD simulation. + comment: Imprint palette positions 1 (#009E73) and 2 (#C475FD) used for before/after. + Red (#AE3030) used semantically for regression. Redundant encoding via position + on x-axis aids CVD safety. - id: VQ-05 name: Layout & Canvas score: 3 max: 4 passed: true - comment: Good proportions and canvas utilization. Legend at top_left is inside - the data area and slightly crowds the Research & Development row at the - top — minor layout issue. + comment: Canvas gate passed (3200x1800). min_border_* values correctly enlarged + to accommodate long labels. Legend placement overlapping bottom data row + is a layout design flaw. - id: VQ-06 name: Axis Labels & Title score: 2 max: 2 passed: true - comment: Title format correct. 'Satisfaction Score' is descriptive; scores - are unitless so no unit suffix needed. 'Department' is appropriate. + comment: Title correctly formatted as 'dumbbell-basic · python · bokeh · anyplot.ai'. + Axis labels 'Satisfaction Score' and 'Department' are descriptive. - id: VQ-07 name: Palette Compliance score: 2 max: 2 passed: true - comment: 'Before dots (#009E73, Imprint pos 1) correct as first series. After - dots (#C475FD, Imprint pos 2) correct. Regression segment uses #AE3030 (semantic - matte red — appropriate for regression/loss). Backgrounds #FAF8F1 light - / #1A1A17 dark correct. Chrome adapts correctly in both renders.' + comment: 'First series (Before dots) = #009E73 ✓. Second series (After dots) + = #C475FD ✓. Red segment #AE3030 is semantic exception for regression ✓. + Backgrounds #FAF8F1 / #1A1A17 correct ✓. Data colors identical across both + renders ✓.' design_excellence: - score: 12 + score: 14 max: 20 items: - id: DE-01 @@ -127,26 +132,26 @@ review: score: 5 max: 8 passed: true - comment: Above defaults. Color-coded segments by improvement/regression direction - is a genuine design choice adding semantic value. Dot outlines and minimal - chrome contribute. Not yet 'FiveThirtyEight-level' publication quality. + comment: 'Above-default design: color-coded segments for direction of change, + white dot edges for separation, delta labels as data annotations. Intentional + palette use with semantic red for regression.' - id: DE-02 name: Visual Refinement score: 4 max: 6 passed: true - comment: 'Good refinement: y-axis spine removed, only x-axis kept, subtle - vertical grid at 10% alpha, generous explicit margins, no Y ticks. Clearly - above minimal-customization level.' + comment: Y-axis spine removed, outline removed, vertical-only grid at 10% + alpha, legend with proper elevated background and muted border. Good overall + refinement. - id: DE-03 name: Data Storytelling - score: 3 + score: 5 max: 6 passed: true - comment: Sorting by delta (ascending) with Finance regression at bottom creates - implicit hierarchy. Red segment highlights the lone regression case. Story - is visible but implicit — no delta labels on segments, no subtitle, viewer - must read the chart to find the Finance outlier. + comment: Ascending sort by delta creates clear visual hierarchy with R&D at + top (+23) as the hero. Red segment for Finance regression creates immediate + contrast. Delta labels make the 'policy change impact' story explicit without + reader having to calculate. spec_compliance: score: 15 max: 15 @@ -156,30 +161,30 @@ review: score: 5 max: 5 passed: true - comment: 'Correct dumbbell chart: two dots per category connected by a line, - horizontal orientation, categories on y-axis.' + comment: 'Correct dumbbell/connected dot plot: horizontal orientation, categories + on y-axis, values on x-axis, two dots per category connected by a line.' - id: SC-02 name: Required Features score: 4 max: 4 passed: true - comment: 'All spec features present: two distinct dot colors, connecting line, - horizontal orientation, sorted by difference, 5-20 categories (8 used).' + comment: Horizontal orientation ✓, distinct colors for start/end dots ✓, connecting + line ✓, sorted by difference ✓ (spec-recommended sort applied). - id: SC-03 name: Data Mapping score: 3 max: 3 passed: true - comment: Categories on y-axis, satisfaction scores on x-axis. Before mapped - to first series (green), After to second series (lavender). All data visible. + comment: Categories on y-axis ✓, satisfaction scores on x-axis ✓, x_range=(45,95) + shows all data correctly ✓. - id: SC-04 name: Title & Legend score: 3 max: 3 passed: true - comment: Title 'dumbbell-basic · python · bokeh · anyplot.ai' correct format. - Legend labels 'Before policy changes' / 'After policy changes' match data - context. + comment: Title 'dumbbell-basic · python · bokeh · anyplot.ai' matches required + format ✓. Legend labels 'Before policy changes' / 'After policy changes' + clearly differentiate the two series ✓. data_quality: score: 15 max: 15 @@ -189,24 +194,25 @@ review: score: 6 max: 6 passed: true - comment: Shows both improvement (7 departments) and regression (Finance, -6 - pts) cases. Sorted by delta to reveal patterns. Covers the full feature - range of a dumbbell chart. + comment: 'Shows all key dumbbell features: direction of change, magnitude, + before/after comparison. Includes one regression (Finance -6) demonstrating + the plot handles both positive and negative deltas.' - id: DQ-02 name: Realistic Context score: 5 max: 5 passed: true - comment: Employee satisfaction scores before/after policy changes — real-world - HR scenario, neutral business domain, plausible department names. + comment: Employee satisfaction scores before/after policy changes is plausible, + neutral, and relatable. 8 departments with scores in 55-88 range are realistic. + No controversial context. - id: DQ-03 name: Appropriate Scale score: 4 max: 4 passed: true - comment: Scores in range 55-88 on a presumed 0-100 scale. Improvements up - to 23 points are plausible. One regression (-6) is realistic. Values are - internally consistent. + comment: 8 categories in 5-20 spec range ✓. Satisfaction scores 55-88 are + realistic for a 0-100 scale. x_range 45-95 provides good padding without + excessive whitespace. code_quality: score: 10 max: 10 @@ -216,37 +222,39 @@ review: score: 3 max: 3 passed: true - comment: 'Linear: self-path fix → imports → constants → data → sort → plot - → save. No functions or classes.' + comment: No functions or classes — straight procedural script with clear section + comments. - id: CQ-02 name: Reproducibility score: 2 max: 2 passed: true - comment: Hardcoded data — fully deterministic, no randomness. + comment: All data is hardcoded inline — fully deterministic, no random state + needed. - id: CQ-03 name: Clean Imports score: 2 max: 2 passed: true - comment: 'All imports used: os/sys/time/pathlib for system ops, bokeh.io/models/plotting - for chart, selenium for screenshot.' + comment: All imports (os, sys, time, Path, bokeh modules, selenium) are used. + No unused imports. - id: CQ-04 name: Code Elegance score: 2 max: 2 passed: true - comment: Clean implementation, no over-engineering. Self-shadowing workaround - is necessary for a file named bokeh.py. List comprehensions are clean. + comment: Clean, well-organized code. HoverTool is real bokeh interactivity + for the HTML artifact, not fake UI. Selenium screenshot pattern is correct + for bokeh catalog renders. - id: CQ-05 name: Output & API score: 1 max: 1 passed: true - comment: Saves plot-{THEME}.png (via Selenium) and plot-{THEME}.html (via - output_file/save). Correct for an interactive library. + comment: Saves plot-{THEME}.png and plot-{THEME}.html as required. Uses current + bokeh 3.x API throughout. library_mastery: - score: 8 + score: 9 max: 10 items: - id: LM-01 @@ -254,26 +262,27 @@ review: score: 5 max: 5 passed: true - comment: ColumnDataSource throughout, HoverTool, output_file/save, theme-adaptive - environment variable pattern, segment() for connecting lines — all idiomatic - Bokeh. + comment: Uses ColumnDataSource for all data, segment() for connecting lines, + scatter() for dots, LabelSet for text overlay, categorical axis via y_range=categories, + proper min_border_* for label room. HTML-first + Selenium screenshot is + the correct bokeh catalog pattern. - id: LM-02 name: Distinctive Features - score: 3 + score: 4 max: 5 passed: true - comment: HoverTool (Bokeh-distinctive interactive feature) and HTML interactive - output are genuinely distinctive. ColumnDataSource with mapped colors per - segment is convenient Bokeh usage. Implementation is solid but fairly standard - — could leverage shared hover across Before/After renderers or custom hover - template showing delta. - verdict: REJECTED + comment: 'HoverTool with multi-field tooltips (Department, Phase, Score, Delta) + ✓. LabelSet for positioned text annotations ✓. Interactive HTML artifact + ✓. ColumnDataSource with rich field dictionaries ✓. Missing: could use Bokeh + Band or Arrow glyphs for more advanced decoration.' + verdict: APPROVED impl_tags: dependencies: - selenium techniques: - hover-tooltips - html-export + - annotations patterns: - columndatasource dataprep: []