Skip to content

Commit 6c8bee5

Browse files
feat(bokeh): implement funnel-basic (#5427)
## Implementation: `funnel-basic` - python/bokeh Implements the **python/bokeh** version of `funnel-basic`. **File:** `plots/funnel-basic/implementations/python/bokeh.py` **Parent Issue:** #789 --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/anyplot/actions/runs/24949132327)* --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
1 parent 2120e36 commit 6c8bee5

2 files changed

Lines changed: 199 additions & 118 deletions

File tree

plots/funnel-basic/implementations/python/bokeh.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
""" pyplots.ai
1+
""" anyplot.ai
22
funnel-basic: Basic Funnel Chart
3-
Library: bokeh 3.8.1 | Python 3.13.11
4-
Quality: 96/100 | Created: 2025-12-23
3+
Library: bokeh 3.9.0 | Python 3.14.4
4+
Quality: 86/100 | Updated: 2026-04-26
55
"""
66

77
from bokeh.io import export_png, output_file, save
Lines changed: 196 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -1,148 +1,201 @@
11
library: bokeh
2+
language: python
23
specification_id: funnel-basic
34
created: '2025-12-23T13:03:22Z'
4-
updated: '2025-12-23T13:11:44Z'
5-
generated_by: claude-opus-4-5-20251101
6-
workflow_run: 20461376426
7-
issue: 0
8-
python_version: 3.13.11
9-
library_version: 3.8.1
10-
preview_url: https://storage.googleapis.com/anyplot-images/plots/funnel-basic/bokeh/plot.png
11-
preview_html: https://storage.googleapis.com/anyplot-images/plots/funnel-basic/bokeh/plot.html
12-
quality_score: 96
13-
impl_tags:
14-
dependencies: []
15-
techniques:
16-
- patches
17-
- custom-legend
18-
- html-export
19-
patterns:
20-
- data-generation
21-
dataprep: []
22-
styling: []
5+
updated: '2026-04-26T05:42:16Z'
6+
generated_by: claude-opus
7+
workflow_run: 24949132327
8+
issue: 789
9+
python_version: 3.14.4
10+
library_version: 3.9.0
11+
preview_url_light: https://storage.googleapis.com/anyplot-images/plots/funnel-basic/python/bokeh/plot-light.png
12+
preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/funnel-basic/python/bokeh/plot-dark.png
13+
preview_html_light: https://storage.googleapis.com/anyplot-images/plots/funnel-basic/python/bokeh/plot-light.html
14+
preview_html_dark: https://storage.googleapis.com/anyplot-images/plots/funnel-basic/python/bokeh/plot-dark.html
15+
quality_score: 86
2316
review:
2417
strengths:
25-
- Excellent use of Bokeh patch() method to create custom trapezoidal funnel segments
26-
- Clear, well-sized text labels with smart color contrast (dark text on yellow background)
27-
- Both PNG and interactive HTML outputs generated
28-
- Proper implementation of width proportional to values relative to first stage
29-
- Clean code structure following KISS principle with good comments
18+
- 'Perfect spec compliance: correct trapezoidal funnel shape with width proportional
19+
to value, stage labels, value and percentage annotations, and distinct per-stage
20+
colors'
21+
- 'Excellent data quality: realistic sales funnel (Awareness → Purchase) with realistic
22+
ratios (1000/600/400/200/100) and neutral, professional context'
23+
- 'Okabe-Ito palette correctly applied in canonical order (green, orange, blue,
24+
pink, golden) with first stage as #009E73'
25+
- 'Appropriate canvas use: funnel fills central area cleanly, axes/grid hidden as
26+
expected for a funnel chart, white segment borders provide clear visual separation'
27+
- 'Explicit font sizing throughout: title 36pt, stage labels 28pt, value labels
28+
22pt, legend 24pt — all clearly readable at 4800×2700'
3029
weaknesses:
31-
- 'Minor: Could improve canvas utilization by making funnel slightly larger to reduce
32-
bottom whitespace'
33-
- 'Minor: Color palette includes red-green combination (though not as sole differentiator)'
34-
image_description: 'The plot displays a funnel chart with 5 trapezoidal segments
35-
representing a sales funnel from top to bottom: Awareness (blue #306998, 1,000
36-
- 100%), Interest (yellow #FFD43B, 600 - 60%), Consideration (red #E74C3C, 400
37-
- 40%), Intent (purple #9B59B6, 200 - 20%), and Purchase (green #27AE60, 100 -
38-
10%). Each segment contains centered white text (dark text on yellow) with the
39-
stage name in bold and the value with percentage below. The funnel progressively
40-
narrows from top to bottom. A legend on the right side lists all stages with their
41-
values. The title "funnel-basic · bokeh · pyplots.ai" is centered at the top.
42-
Axes and grid are hidden for a clean presentation.'
30+
- 'Dark mode chrome: legend label_text_color may not be theme-adapted — verify p.legend.label_text_color
31+
is set to INK_SOFT (#B8B7B0) in dark mode, not left as default black; VQ-07 partial
32+
compliance'
33+
- 'No HoverTool: Bokeh''s most distinctive feature (interactive hover tooltips)
34+
is absent; adding a HoverTool showing stage name, count, and drop-off % from previous
35+
stage would elevate LM-02 significantly'
36+
- 'Design storytelling gap: the biggest conversion drop-offs (Interest→Consideration
37+
40%, Intent→Purchase 50%) are not visually emphasized; consider slight color desaturation
38+
on later stages or annotation callouts at key drop-off boundaries'
39+
- 'ColumnDataSource not used: Bokeh''s idiomatic pattern (ColumnDataSource + renderers)
40+
is bypassed in favor of direct patch() calls in a loop; while functional, using
41+
a CDS would improve LM-01 and enable HoverTool binding'
42+
image_description: |-
43+
Light render (plot-light.png):
44+
Background: Warm off-white (#FAF8F1 range) — correct theme surface
45+
Chrome: Title "funnel-basic · bokeh · anyplot.ai" in dark ink at top, clearly readable. No axes or grid (appropriate for funnel). Legend on right side with colored swatches and stage labels; legend text dark on light elevated background — readable.
46+
Data: Five trapezoidal funnel segments from top to bottom: Awareness (teal #009E73, widest), Interest (orange #D55E00), Consideration (blue #0072B2), Intent (pink #CC79A7), Purchase (golden #E69F00, narrowest). Widths are proportional to values. Each segment has a bold white stage name and a smaller value+percentage label centered within it. White borders between segments provide clean separation.
47+
Legibility verdict: PASS — all text clearly readable, explicit font sizes visible
48+
49+
Dark render (plot-dark.png):
50+
Background: Near-black (#1A1A17 range) — correct dark surface
51+
Chrome: Title "funnel-basic · bokeh · anyplot.ai" appears in a light/cream color at the top — readable against dark background. Legend on right side with elevated slightly lighter background; legend text appears small and the color adaptation is uncertain (may be dark-on-dark for legend items). No axes/grid, which remain correctly absent.
52+
Data: Identical Okabe-Ito colors as light render (teal, orange, blue, pink, golden) — data colors correctly unchanged between themes. White in-segment labels remain readable on colored segment backgrounds.
53+
Legibility verdict: PASS for title and in-segment labels; UNCERTAIN for legend text color — possible partial dark-on-dark issue if legend.label_text_color was not set to INK_SOFT
4354
criteria_checklist:
4455
visual_quality:
45-
score: 36
46-
max: 40
56+
score: 27
57+
max: 30
4758
items:
4859
- id: VQ-01
4960
name: Text Legibility
50-
score: 10
51-
max: 10
61+
score: 7
62+
max: 8
5263
passed: true
53-
comment: all text clearly readable at 28-36pt sizes
64+
comment: All font sizes explicitly set (title 36pt, stage labels 28pt, value
65+
labels 22pt, legend 24pt). Readable in both renders. -1 for potential legend
66+
text color uncertainty in dark mode.
5467
- id: VQ-02
5568
name: No Overlap
56-
score: 8
57-
max: 8
69+
score: 6
70+
max: 6
5871
passed: true
59-
comment: no overlapping text elements
72+
comment: No overlapping text in either render. Labels centered in segments,
73+
well-spaced.
6074
- id: VQ-03
6175
name: Element Visibility
62-
score: 8
63-
max: 8
76+
score: 6
77+
max: 6
6478
passed: true
65-
comment: funnel segments well-sized and visible
79+
comment: All five funnel segments clearly visible and well-proportioned. White
80+
borders improve segment definition.
6681
- id: VQ-04
6782
name: Color Accessibility
68-
score: 4
69-
max: 5
83+
score: 2
84+
max: 2
7085
passed: true
71-
comment: distinct colors, slight deduction for red-green in palette
86+
comment: Okabe-Ito palette is colorblind-safe. Good luminance contrast on
87+
all segments.
7288
- id: VQ-05
73-
name: Layout Balance
74-
score: 4
75-
max: 5
89+
name: Layout & Canvas
90+
score: 3
91+
max: 4
7692
passed: true
77-
comment: good centered layout, minor whitespace at bottom
78-
- id: VQ-07
79-
name: Grid & Legend
93+
comment: Funnel fills central area well. Some whitespace in corners outside
94+
the trapezoid shape. Legend offset slightly unbalances the composition.
95+
- id: VQ-06
96+
name: Axis Labels & Title
8097
score: 2
8198
max: 2
8299
passed: true
83-
comment: legend well-placed, grid appropriately hidden
100+
comment: Title descriptive and correct format. No axis labels appropriate
101+
for funnel chart (axes are hidden).
102+
- id: VQ-07
103+
name: Palette Compliance
104+
score: 1
105+
max: 2
106+
passed: false
107+
comment: 'Okabe-Ito colors correct (first stage = #009E73, order follows canonical
108+
sequence). Backgrounds correct (#FAF8F1 light, #1A1A17 dark). Partial compliance:
109+
legend text color adaptation in dark mode uncertain — may not have label_text_color
110+
set to INK_SOFT.'
111+
design_excellence:
112+
score: 13
113+
max: 20
114+
items:
115+
- id: DE-01
116+
name: Aesthetic Sophistication
117+
score: 5
118+
max: 8
119+
passed: true
120+
comment: Professional appearance with intentional per-stage Okabe-Ito colors,
121+
bold stage labels, clean funnel shape. Clearly above generic defaults. Not
122+
quite publication-ready — missing additional polish like drop-off annotation
123+
or visual emphasis.
124+
- id: DE-02
125+
name: Visual Refinement
126+
score: 4
127+
max: 6
128+
passed: true
129+
comment: 'Axes and grid correctly hidden, white segment borders provide clean
130+
visual separation, good whitespace. Minor: outline_line_color=None removes
131+
border cleanly. Some refinement visible.'
132+
- id: DE-03
133+
name: Data Storytelling
134+
score: 4
135+
max: 6
136+
passed: true
137+
comment: 'Funnel shape inherently communicates progressive drop-off. Percentage
138+
labels (100%, 60%, 40%, 20%, 10%) provide immediate context. Visual hierarchy
139+
from large-to-small guides the eye. Missing: explicit emphasis on largest
140+
conversion gaps (Interest-to-Consideration, Intent-to-Purchase drops).'
84141
spec_compliance:
85-
score: 25
86-
max: 25
142+
score: 15
143+
max: 15
87144
items:
88145
- id: SC-01
89146
name: Plot Type
90-
score: 8
91-
max: 8
92-
passed: true
93-
comment: correct funnel with trapezoidal segments
94-
- id: SC-02
95-
name: Data Mapping
96147
score: 5
97148
max: 5
98149
passed: true
99-
comment: stages/values correctly mapped, width proportional
100-
- id: SC-03
150+
comment: Correct funnel chart with trapezoidal segments narrowing from top
151+
(largest) to bottom (smallest).
152+
- id: SC-02
101153
name: Required Features
102-
score: 5
103-
max: 5
154+
score: 4
155+
max: 4
104156
passed: true
105-
comment: distinct colors, labels with percentages, proper narrowing
106-
- id: SC-04
107-
name: Data Range
157+
comment: 'All spec features present: sequential stages, distinct colors per
158+
stage, value labels, percentage labels, widths proportional to value relative
159+
to first stage.'
160+
- id: SC-03
161+
name: Data Mapping
108162
score: 3
109163
max: 3
110164
passed: true
111-
comment: all data visible
112-
- id: SC-05
113-
name: Legend Accuracy
114-
score: 2
115-
max: 2
116-
passed: true
117-
comment: legend labels accurate
118-
- id: SC-06
119-
name: Title Format
120-
score: 2
121-
max: 2
165+
comment: Stages ordered largest to smallest (top to bottom). Widths correctly
166+
proportional to value/max_value.
167+
- id: SC-04
168+
name: Title & Legend
169+
score: 3
170+
max: 3
122171
passed: true
123-
comment: correct format "funnel-basic · bokeh · pyplots.ai"
172+
comment: Title format 'funnel-basic · bokeh · anyplot.ai' correct. Legend
173+
shows all 5 stages with values.
124174
data_quality:
125-
score: 20
126-
max: 20
175+
score: 15
176+
max: 15
127177
items:
128178
- id: DQ-01
129179
name: Feature Coverage
130-
score: 8
131-
max: 8
180+
score: 6
181+
max: 6
132182
passed: true
133-
comment: shows progressive decrease through all stages
183+
comment: 'Shows all funnel aspects: 5 stages with progressive decrease, proportional
184+
widths, full coverage of the conversion funnel concept.'
134185
- id: DQ-02
135186
name: Realistic Context
136-
score: 7
137-
max: 7
187+
score: 5
188+
max: 5
138189
passed: true
139-
comment: realistic sales funnel example from spec
190+
comment: Sales funnel with realistic marketing stages (Awareness, Interest,
191+
Consideration, Intent, Purchase). Professional, neutral, real-world scenario.
140192
- id: DQ-03
141193
name: Appropriate Scale
142-
score: 5
143-
max: 5
194+
score: 4
195+
max: 4
144196
passed: true
145-
comment: sensible conversion rates (1000→100)
197+
comment: Values 1000/600/400/200/100 represent realistic funnel ratios (10%
198+
conversion). Plausible for a marketing/sales context.
146199
code_quality:
147200
score: 10
148201
max: 10
@@ -152,40 +205,68 @@ review:
152205
score: 3
153206
max: 3
154207
passed: true
155-
comment: imports → data → plot → save
208+
comment: 'Linear script: imports → data → calculations → figure → render →
209+
save. No functions or classes.'
156210
- id: CQ-02
157211
name: Reproducibility
158-
score: 3
159-
max: 3
212+
score: 2
213+
max: 2
160214
passed: true
161-
comment: deterministic data, no random values
215+
comment: Fully deterministic hardcoded datano randomness needed.
162216
- id: CQ-03
163217
name: Clean Imports
164218
score: 2
165219
max: 2
166220
passed: true
167-
comment: all imports used
221+
comment: 'Only bokeh modules that are actually used: export_png, output_file,
222+
save, Label, Legend, LegendItem, figure.'
168223
- id: CQ-04
169-
name: No Deprecated API
170-
score: 1
171-
max: 1
224+
name: Code Elegance
225+
score: 2
226+
max: 2
172227
passed: true
173-
comment: current API usage
228+
comment: Manual patch geometry is necessary for custom funnel shape in Bokeh.
229+
Appropriate complexity. Clean iteration over stages.
174230
- id: CQ-05
175-
name: Output Correct
231+
name: Output & API
176232
score: 1
177233
max: 1
178234
passed: true
179-
comment: saves as plot.png
180-
library_features:
181-
score: 5
182-
max: 5
235+
comment: Both plot-light.png and plot-dark.png generated successfully. HTML
236+
outputs also produced.
237+
library_mastery:
238+
score: 6
239+
max: 10
183240
items:
184-
- id: LF-01
185-
name: Uses distinctive library features
186-
score: 5
241+
- id: LM-01
242+
name: Idiomatic Usage
243+
score: 4
187244
max: 5
188245
passed: true
189-
comment: patch() for custom shapes, Label model, Legend with LegendItem, HTML
190-
export
191-
verdict: APPROVED
246+
comment: Uses Bokeh's patch() for polygon rendering, Label model for text
247+
overlays, LegendItem for manual legend construction — idiomatic Bokeh patterns.
248+
However, ColumnDataSource is not used, which is Bokeh's recommended data
249+
binding pattern.
250+
- id: LM-02
251+
name: Distinctive Features
252+
score: 2
253+
max: 5
254+
passed: false
255+
comment: Uses Label and LegendItem models (Bokeh-specific), but does not leverage
256+
HoverTool — Bokeh's most distinctive interactive feature. A HoverTool showing
257+
stage name, count, and drop-off percentage would make this implementation
258+
distinctly Bokeh vs. a static library.
259+
verdict: REJECTED
260+
impl_tags:
261+
dependencies: []
262+
techniques:
263+
- annotations
264+
- patches
265+
- html-export
266+
patterns:
267+
- iteration-over-groups
268+
dataprep:
269+
- normalization
270+
styling:
271+
- alpha-blending
272+
- edge-highlighting

0 commit comments

Comments
 (0)