Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions plots/indicator-bollinger/implementations/python/pygal.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
""" pyplots.ai
""" anyplot.ai
indicator-bollinger: Bollinger Bands Indicator Chart
Library: pygal 3.1.0 | Python 3.13.11
Quality: 90/100 | Created: 2026-01-07
Library: pygal 3.1.0 | Python 3.13.13
Quality: 67/100 | Updated: 2026-05-17
"""

import numpy as np
Expand Down
259 changes: 138 additions & 121 deletions plots/indicator-bollinger/metadata/python/pygal.yaml
Original file line number Diff line number Diff line change
@@ -1,200 +1,218 @@
library: pygal
language: python
specification_id: indicator-bollinger
created: '2026-01-07T20:21:42Z'
updated: '2026-01-07T20:39:10Z'
generated_by: claude-opus-4-5-20251101
workflow_run: 20795219305
updated: '2026-05-17T10:13:28Z'
generated_by: claude-haiku
workflow_run: 25987481141
issue: 3237
python_version: 3.13.11
language_version: 3.13.13
library_version: 3.1.0
preview_url: https://storage.googleapis.com/anyplot-images/plots/indicator-bollinger/pygal/plot.png
preview_html: https://storage.googleapis.com/anyplot-images/plots/indicator-bollinger/pygal/plot.html
quality_score: 90
preview_url_light: https://storage.googleapis.com/anyplot-images/plots/indicator-bollinger/python/pygal/plot-light.png
preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/indicator-bollinger/python/pygal/plot-dark.png
preview_html_light: https://storage.googleapis.com/anyplot-images/plots/indicator-bollinger/python/pygal/plot-light.html
preview_html_dark: https://storage.googleapis.com/anyplot-images/plots/indicator-bollinger/python/pygal/plot-dark.html
quality_score: 67
review:
strengths:
- Clear visual representation of all four Bollinger Band components
- Good use of pygal custom Style for font sizing and colors
- SMA correctly rendered as dashed line per spec requirements
- Appropriate data generation with realistic stock price movements
- Proper 120-day trading period as specified
- Legend placement at bottom keeps chart area clean
- 'Both renders display correct background colors (#FAF8F1 light, #1A1A17 dark)'
- Proper Bollinger Bands mathematical calculation (20-period SMA with 2 std dev)
- All required data series are visualized
- Text is readable in both light and dark themes
- Realistic, non-controversial synthetic data
weaknesses:
- Fill is applied to baseline rather than between upper and lower bands (pygal limitation
- acceptable workaround)
- The fill-to-baseline approach creates visual clutter making bands harder to distinguish
image_description: 'The plot displays a Bollinger Bands indicator chart for 120
trading days. The chart shows four distinct series: a dark blue "Close Price"
line showing volatile price movements starting around $151 and trending down to
around $137 by day 120, with significant fluctuations throughout. The "Upper Band"
(light steel blue) and "Lower Band" (light blue/teal) create a volatility envelope
around the price, both rendered with fill-to-baseline. The "SMA (20)" middle band
is shown as a dashed yellow/gold line tracking the moving average. The title correctly
displays "indicator-bollinger · pygal · pyplots.ai". X-axis shows "Trading Day"
with labels at Day 1, 21, 41, 61, 81, and 101 (rotated 45°). Y-axis shows "Price
(USD)" ranging from ~126 to ~164. Legend is positioned at bottom with colored
squares for each series.'
- 'Palette non-compliance: uses arbitrary colors instead of Okabe-Ito; fails CVD
safety requirement'
- 'Theme adaptation failure: code doesn''t read ANYPLOT_THEME; hardcoded for light
theme'
- 'Title format incorrect: should be ''indicator-bollinger · pygal · anyplot.ai''
(note: anyplot, not pyplots)'
- 'Wrong output filenames: uses ''plot.png'' instead of theme-aware ''plot-{THEME}.png'''
- 'Band visualization unclear: lines shown separately; no clear semi-transparent
fill as spec requests'
- 'Design excellence absent: no custom styling or visual hierarchy'
image_description: |-
Light render (plot-light.png):
Background: Warm off-white (#FAF8F1) - CORRECT
Chrome: Title "Bollinger Band Indicator", axis labels "Trading Day" / "Price (USD)" visible and readable with dark text
Data: Blue Close Price line, cyan upper/lower band lines, orange-gold SMA (20) dashed line
Legibility verdict: PASS - all text elements readable

Dark render (plot-dark.png):
Background: Warm near-black (#1A1A17) - CORRECT
Chrome: Title, axis labels visible with light text, good contrast, no dark-on-dark failures
Data: Colors identical to light render (blue, cyan, orange) - correct theme-independence
Legibility verdict: PASS - all text readable, no contrast issues
criteria_checklist:
visual_quality:
score: 36
max: 40
score: 21
max: 30
items:
- id: VQ-01
name: Text Legibility
score: 9
max: 10
score: 7
max: 8
passed: true
comment: Title, axis labels, and legend text clearly readable. Tick labels
slightly small but acceptable.
comment: Most text readable; legend could be larger
- id: VQ-02
name: No Overlap
score: 8
max: 8
score: 5
max: 6
passed: true
comment: No overlapping text elements. X-axis labels properly rotated and
spaced.
comment: Some overlap where lines cross but distinguishable
- id: VQ-03
name: Element Visibility
score: 7
max: 8
score: 5
max: 6
passed: true
comment: Lines visible and distinguishable. Fill creates some visual clutter
but bands identifiable.
comment: All visible; band fill effect unclear
- id: VQ-04
name: Color Accessibility
score: 5
max: 5
passed: true
comment: 'Good color choices: blue, gold/yellow, steel blue - distinguishable
for colorblind users.'
score: 0
max: 2
passed: false
comment: Colors not Okabe-Ito; lacks CVD safety
- id: VQ-05
name: Layout Balance
score: 4
max: 5
name: Layout & Canvas
score: 3
max: 4
passed: true
comment: Plot fills canvas well, minor excess whitespace on right side.
comment: Good proportions; legend slightly cramped
- id: VQ-06
name: Axis Labels
score: 2
name: Axis Labels & Title
score: 1
max: 2
passed: true
comment: Price (USD) and Trading Day are descriptive with units.
passed: false
comment: Axis labels good; title format incorrect
- id: VQ-07
name: Grid & Legend
score: 1
name: Palette Compliance
score: 0
max: 2
passed: false
comment: Not Okabe-Ito; no theme adaptation
design_excellence:
score: 7
max: 20
items:
- id: DE-01
name: Aesthetic Sophistication
score: 2
max: 8
passed: false
comment: Generic styling, arbitrary colors
- id: DE-02
name: Visual Refinement
score: 2
max: 6
passed: false
comment: Minimal customization
- id: DE-03
name: Data Storytelling
score: 3
max: 6
passed: true
comment: Legend well placed at bottom; y-guides present but subtle.
comment: Shows data but lacks hierarchy
spec_compliance:
score: 23
max: 25
score: 13
max: 15
items:
- id: SC-01
name: Plot Type
score: 8
max: 8
passed: true
comment: Correct line chart showing Bollinger Bands components.
- id: SC-02
name: Data Mapping
score: 5
max: 5
passed: true
comment: Time on X-axis, price on Y-axis correctly mapped.
- id: SC-03
comment: Line chart correct
- id: SC-02
name: Required Features
score: 4
max: 5
score: 3
max: 4
passed: true
comment: Shows close price, SMA, upper and lower bands. Fill between bands
not native to pygal.
- id: SC-04
name: Data Range
comment: All series present; band visualization unclear
- id: SC-03
name: Data Mapping
score: 3
max: 3
passed: true
comment: All 120 days visible, Y-axis range appropriate.
- id: SC-05
name: Legend Accuracy
comment: X/Y correct
- id: SC-04
name: Title & Legend
score: 2
max: 2
passed: true
comment: 'Legend labels accurate: Close Price, SMA (20), Upper Band, Lower
Band.'
- id: SC-06
name: Title Format
score: 1
max: 2
passed: true
comment: Correct format with spec-id, library, and pyplots.ai.
max: 3
passed: false
comment: Title format incorrect
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 volatility patterns, band contraction/expansion, price touching
bands.
comment: All aspects shown
- id: DQ-02
name: Realistic Context
score: 7
max: 7
score: 5
max: 5
passed: true
comment: Stock price scenario is realistic and neutral.
comment: Realistic BB calculation
- id: DQ-03
name: Appropriate Scale
score: 4
max: 5
max: 4
passed: true
comment: Price range ($126-164) realistic for stock. 120 days appropriate.
comment: Sensible values
code_quality:
score: 10
score: 8
max: 10
items:
- id: CQ-01
name: KISS Structure
score: 3
max: 3
passed: true
comment: Follows imports → data → plot → save pattern without functions/classes.
comment: Simple structure
- id: CQ-02
name: Reproducibility
score: 3
max: 3
score: 2
max: 2
passed: true
comment: Uses np.random.seed(42).
comment: Has seed
- id: CQ-03
name: Clean Imports
score: 2
max: 2
passed: true
comment: Only necessary imports (numpy, pygal, Style).
comment: Only used imports
- id: CQ-04
name: No Deprecated API
name: Code Elegance
score: 1
max: 1
passed: true
comment: Uses current pygal API.
max: 2
passed: false
comment: Hardcoded for light theme
- id: CQ-05
name: Output Correct
score: 1
name: Output & API
score: 0
max: 1
passed: true
comment: Saves as plot.png and plot.html.
library_features:
passed: false
comment: Wrong filenames
library_mastery:
score: 3
max: 5
max: 10
items:
- id: LF-01
- id: LM-01
name: Idiomatic Usage
score: 2
max: 5
passed: false
comment: No ANYPLOT_THEME integration
- id: LM-02
name: Distinctive Features
score: 3
score: 1
max: 5
passed: true
comment: Uses pygal Style customization, cubic interpolation, stroke_style
with dasharray. Fill-between not native to pygal.
verdict: APPROVED
passed: false
comment: Generic usage
verdict: REJECTED
impl_tags:
dependencies: []
techniques:
Expand All @@ -203,5 +221,4 @@ impl_tags:
- data-generation
dataprep:
- rolling-window
styling:
- grid-styling
styling: []
Loading