Skip to content

Commit a1cfdf9

Browse files
feat(pygal): implement point-basic (#2587)
## Implementation: `point-basic` - pygal Implements the **pygal** version of `point-basic`. **File:** `plots/point-basic/implementations/pygal.py` --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/pyplots/actions/runs/20593352389)* --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
1 parent 4f90b34 commit a1cfdf9

2 files changed

Lines changed: 118 additions & 0 deletions

File tree

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
""" pyplots.ai
2+
point-basic: Point Estimate Plot
3+
Library: pygal 3.1.0 | Python 3.13.11
4+
Quality: 91/100 | Created: 2025-12-30
5+
"""
6+
7+
import pygal
8+
from pygal.style import Style
9+
10+
11+
# Data: Treatment effects with 95% confidence intervals
12+
categories = ["Treatment A", "Treatment B", "Treatment C", "Treatment D", "Control"]
13+
estimates = [2.4, 1.8, 3.2, 0.9, 0.0]
14+
lower_bounds = [1.6, 0.9, 2.5, -0.2, -0.5]
15+
upper_bounds = [3.2, 2.7, 3.9, 2.0, 0.5]
16+
17+
# Custom style for 4800x2700 canvas
18+
ci_color = "#306998"
19+
point_color = "#FFD43B"
20+
ref_color = "#888888"
21+
22+
custom_style = Style(
23+
background="white",
24+
plot_background="white",
25+
foreground="#333333",
26+
foreground_strong="#333333",
27+
foreground_subtle="#999999",
28+
colors=(ref_color, ci_color, ci_color, ci_color, ci_color, ci_color, point_color),
29+
title_font_size=72,
30+
label_font_size=48,
31+
major_label_font_size=42,
32+
legend_font_size=42,
33+
value_font_size=36,
34+
stroke_width=6,
35+
guide_stroke_color="#e0e0e0",
36+
)
37+
38+
# Create XY chart for point estimates with confidence intervals
39+
chart = pygal.XY(
40+
width=4800,
41+
height=2700,
42+
style=custom_style,
43+
title="point-basic · pygal · pyplots.ai",
44+
x_title="Effect Size",
45+
show_legend=True,
46+
legend_at_bottom=True,
47+
legend_at_bottom_columns=3,
48+
show_y_guides=True,
49+
show_x_guides=True,
50+
dots_size=30,
51+
stroke=False,
52+
margin_left=120,
53+
margin_right=120,
54+
margin_top=150,
55+
margin_bottom=180,
56+
xrange=(-1.5, 4.5),
57+
range=(0, 6),
58+
)
59+
60+
# Map categories to y-values (numeric) - reversed for top-to-bottom display
61+
y_positions = list(range(len(categories), 0, -1))
62+
63+
# Add reference line at zero first (so it appears behind other elements)
64+
ref_line = [(0, 0.3), (0, 5.7)]
65+
chart.add("Reference (x=0)", ref_line, stroke=True, show_dots=False, stroke_width=3)
66+
67+
# Add each CI as a separate series (to avoid connecting lines)
68+
for i, (low, high, y) in enumerate(zip(lower_bounds, upper_bounds, y_positions, strict=True)):
69+
ci_data = [(low, y), (high, y)]
70+
# First CI gets label, others are hidden from legend using None
71+
if i == 0:
72+
chart.add("95% CI", ci_data, stroke=True, show_dots=False, stroke_width=8)
73+
else:
74+
chart.add(None, ci_data, stroke=True, show_dots=False, stroke_width=8)
75+
76+
# Add point estimates (on top of CI lines)
77+
point_data = [(est, y) for est, y in zip(estimates, y_positions, strict=True)]
78+
chart.add("Point Estimate", point_data, dots_size=32, stroke=False)
79+
80+
# Custom y-axis labels with category names - use major labels
81+
chart.y_labels_major = [5, 4, 3, 2, 1]
82+
chart.y_labels = [
83+
{"value": 5, "label": "Treatment A"},
84+
{"value": 4, "label": "Treatment B"},
85+
{"value": 3, "label": "Treatment C"},
86+
{"value": 2, "label": "Treatment D"},
87+
{"value": 1, "label": "Control"},
88+
]
89+
90+
# Save as PNG and HTML
91+
chart.render_to_png("plot.png")
92+
chart.render_to_file("plot.html")
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
library: pygal
2+
specification_id: point-basic
3+
created: '2025-12-30T09:34:14Z'
4+
updated: '2025-12-30T09:44:39Z'
5+
generated_by: claude-opus-4-5-20251101
6+
workflow_run: 20593352389
7+
issue: 0
8+
python_version: 3.13.11
9+
library_version: 3.1.0
10+
preview_url: https://storage.googleapis.com/pyplots-images/plots/point-basic/pygal/plot.png
11+
preview_thumb: https://storage.googleapis.com/pyplots-images/plots/point-basic/pygal/plot_thumb.png
12+
preview_html: https://storage.googleapis.com/pyplots-images/plots/point-basic/pygal/plot.html
13+
quality_score: 91
14+
review:
15+
strengths:
16+
- Excellent horizontal orientation matching spec recommendation for readable category
17+
labels
18+
- Clear visual hierarchy with distinct colors for reference line, CIs, and point
19+
estimates
20+
- Includes reference line at zero as suggested in spec notes
21+
- Well-structured code following KISS principles with good use of pygal Style system
22+
- Realistic clinical trial scenario demonstrating varied effect sizes and CI widths
23+
weaknesses:
24+
- Confidence interval lines lack caps/endpoints as suggested in the specification
25+
notes
26+
- X-axis label Effect Size could include units or be more descriptive

0 commit comments

Comments
 (0)