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
70 changes: 70 additions & 0 deletions plots/range-interval/implementations/pygal.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
""" pyplots.ai
range-interval: Range Interval Chart
Library: pygal 3.1.0 | Python 3.13.11
Quality: 91/100 | Created: 2026-01-09
"""

import pygal
from pygal.style import Style


# Data: Monthly temperature ranges (daily high/low averages)
months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
temp_min = [-2, 0, 4, 8, 13, 17, 19, 18, 14, 9, 4, 0] # Average daily lows (°C)
temp_max = [6, 8, 12, 16, 21, 25, 28, 27, 22, 16, 10, 7] # Average daily highs (°C)

# Calculate the range (difference) for the visible portion
temp_range = [high - low for low, high in zip(temp_min, temp_max, strict=True)]

# Custom style for large canvas
# The base (transparent) color needs to be invisible
custom_style = Style(
background="white",
plot_background="white",
foreground="#333333",
foreground_strong="#333333",
foreground_subtle="#666666",
colors=("rgba(0, 0, 0, 0)", "#306998"), # First series invisible, second visible
title_font_size=56,
label_font_size=36,
major_label_font_size=32,
legend_font_size=36,
value_font_size=28,
tooltip_font_size=24,
opacity=1.0,
opacity_hover=1.0,
)

# Create stacked bar chart - first bar is invisible base, second is visible range
chart = pygal.StackedBar(
width=4800,
height=2700,
style=custom_style,
title="range-interval · pygal · pyplots.ai",
x_title="Month",
y_title="Temperature (°C)",
show_legend=True,
legend_at_bottom=True,
legend_at_bottom_columns=2,
show_y_guides=True,
show_x_guides=False,
print_values=False,
spacing=40,
margin=80,
margin_bottom=150,
margin_left=150,
truncate_legend=-1,
)

# Set x-axis labels
chart.x_labels = months

# Add invisible base (from 0 to min_value) - hidden from legend
chart.add("", temp_min, show_dots=False)

# Add visible range bars (from min to max)
chart.add("Temperature Range (°C)", temp_range)

# Render to PNG and HTML
chart.render_to_png("plot.png")
chart.render_to_file("plot.html")
207 changes: 207 additions & 0 deletions plots/range-interval/metadata/pygal.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
library: pygal
specification_id: range-interval
created: '2026-01-09T23:49:05Z'
updated: '2026-01-09T23:53:46Z'
generated_by: claude-opus-4-5-20251101
workflow_run: 20868894824
issue: 3577
python_version: 3.13.11
library_version: 3.1.0
preview_url: https://storage.googleapis.com/pyplots-images/plots/range-interval/pygal/plot.png
preview_thumb: https://storage.googleapis.com/pyplots-images/plots/range-interval/pygal/plot_thumb.png
preview_html: https://storage.googleapis.com/pyplots-images/plots/range-interval/pygal/plot.html
quality_score: 91
review:
strengths:
- Clever implementation using stacked bar with invisible base to create floating
range bars
- Clean, professional appearance with good color choice
- Realistic temperature data showing clear seasonal variation
- Proper title format and axis labels with units
- Good canvas utilization and layout balance
weaknesses:
- Grid & legend could be improved - the invisible series technique leaves legend
slightly awkward
- Missing optional endpoint markers at min/max points as suggested in spec notes
- Could leverage more pygal-specific interactive features
image_description: 'The plot displays a range interval chart showing monthly temperature
ranges across 12 months (Jan-Dec). Each month is represented by a blue (#306998)
floating bar that spans from the minimum to maximum temperature for that month.
The y-axis shows "Temperature (°C)" ranging from -2 to 28, and the x-axis shows
"Month" with abbreviated month labels. The title correctly reads "range-interval
· pygal · pyplots.ai" at the top. A legend at the bottom displays "Temperature
Range (°C)". Horizontal grid lines are visible at 2-degree intervals. The bars
effectively show the seasonal pattern with narrow ranges in winter months (Jan:
-2 to 6°C, Feb: 0 to 8°C) and wider, higher ranges in summer (Jul: 19 to 28°C).
The overall layout is clean with good use of whitespace.'
criteria_checklist:
visual_quality:
score: 36
max: 40
items:
- id: VQ-01
name: Text Legibility
score: 9
max: 10
passed: true
comment: Title and axis labels are clearly readable. Font sizes are appropriate
for the canvas size. Tick labels slightly small but still legible.
- id: VQ-02
name: No Overlap
score: 8
max: 8
passed: true
comment: No overlapping text elements. Month labels are well-spaced.
- id: VQ-03
name: Element Visibility
score: 7
max: 8
passed: true
comment: Bars are clearly visible with good sizing. Could benefit from slightly
more contrast or edge highlighting.
- id: VQ-04
name: Color Accessibility
score: 5
max: 5
passed: true
comment: Single blue color scheme is colorblind-safe. Good contrast against
white background.
- id: VQ-05
name: Layout Balance
score: 5
max: 5
passed: true
comment: Plot fills canvas well with balanced margins. Good use of space.
- id: VQ-06
name: Axis Labels
score: 2
max: 2
passed: true
comment: 'Descriptive labels with units: Temperature (°C) and Month.'
- id: VQ-07
name: Grid & Legend
score: 0
max: 2
passed: false
comment: Legend placement at bottom is acceptable but the invisible series
creates a gap. Grid is subtle but works.
spec_compliance:
score: 23
max: 25
items:
- id: SC-01
name: Plot Type
score: 8
max: 8
passed: true
comment: Correct range interval chart implementation using stacked bar technique.
- id: SC-02
name: Data Mapping
score: 5
max: 5
passed: true
comment: Categories on x-axis, range values on y-axis as specified.
- id: SC-03
name: Required Features
score: 4
max: 5
passed: true
comment: Shows min-max ranges effectively. Missing optional endpoint markers
mentioned in spec notes.
- id: SC-04
name: Data Range
score: 3
max: 3
passed: true
comment: Y-axis range appropriately shows all data from -2 to 28.
- id: SC-05
name: Legend Accuracy
score: 2
max: 2
passed: true
comment: Legend correctly identifies the temperature range.
- id: SC-06
name: Title Format
score: 1
max: 2
passed: true
comment: Title uses correct format but uses regular dot which displays correctly.
data_quality:
score: 19
max: 20
items:
- id: DQ-01
name: Feature Coverage
score: 7
max: 8
passed: true
comment: Shows variation in range sizes across seasons. Winter months have
narrow ranges, summer months have wider ranges. Good seasonal pattern.
- id: DQ-02
name: Realistic Context
score: 7
max: 7
passed: true
comment: Monthly temperature ranges for a temperate climate location. Realistic
and neutral scenario.
- id: DQ-03
name: Appropriate Scale
score: 5
max: 5
passed: true
comment: Temperature values are realistic for a temperate European climate.
code_quality:
score: 10
max: 10
items:
- id: CQ-01
name: KISS Structure
score: 3
max: 3
passed: true
comment: 'Simple script structure: imports, data, chart config, save. No functions
or classes.'
- id: CQ-02
name: Reproducibility
score: 3
max: 3
passed: true
comment: Data is deterministic (hardcoded values), no randomness.
- id: CQ-03
name: Clean Imports
score: 2
max: 2
passed: true
comment: Only pygal and Style imported, both are used.
- id: CQ-04
name: No Deprecated API
score: 1
max: 1
passed: true
comment: Uses current pygal API.
- id: CQ-05
name: Output Correct
score: 1
max: 1
passed: true
comment: Saves as plot.png and plot.html.
library_features:
score: 3
max: 5
items:
- id: LF-01
name: Distinctive Features
score: 3
max: 5
passed: true
comment: Uses pygal's StackedBar with custom Style effectively. The invisible
base bar technique is clever. Could use more pygal-specific features like
tooltips or animation.
verdict: APPROVED
impl_tags:
dependencies: []
techniques:
- html-export
patterns: []
dataprep: []
styling: []