Skip to content

Commit b89608f

Browse files
feat(pygal): implement line-loss-training (#2910)
## Implementation: `line-loss-training` - pygal Implements the **pygal** version of `line-loss-training`. **File:** `plots/line-loss-training/implementations/pygal.py` **Parent Issue:** #2860 --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/pyplots/actions/runs/20608711859)* --------- 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 676f2ac commit b89608f

2 files changed

Lines changed: 103 additions & 0 deletions

File tree

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
""" pyplots.ai
2+
line-loss-training: Training Loss Curve
3+
Library: pygal 3.1.0 | Python 3.13.11
4+
Quality: 91/100 | Created: 2025-12-31
5+
"""
6+
7+
import numpy as np
8+
import pygal
9+
from pygal.style import Style
10+
11+
12+
# Data: Simulated training loss curves showing typical overfitting behavior
13+
np.random.seed(42)
14+
epochs = np.arange(1, 51)
15+
16+
# Training loss: Steadily decreasing with some noise
17+
train_loss = 2.5 * np.exp(-0.08 * epochs) + 0.1 + np.random.normal(0, 0.02, len(epochs))
18+
19+
# Validation loss: Decreases then increases (overfitting after epoch ~30)
20+
val_loss = 2.3 * np.exp(-0.07 * epochs) + 0.15 + 0.003 * np.maximum(0, epochs - 25) ** 1.5
21+
val_loss += np.random.normal(0, 0.03, len(epochs))
22+
23+
# Find minimum validation loss epoch for annotation
24+
min_val_epoch = int(epochs[np.argmin(val_loss)])
25+
min_val_loss = float(np.min(val_loss))
26+
27+
# Custom style for large canvas
28+
custom_style = Style(
29+
background="white",
30+
plot_background="white",
31+
foreground="#333333",
32+
foreground_strong="#333333",
33+
foreground_subtle="#666666",
34+
colors=("#306998", "#FFD43B"), # Python Blue, Python Yellow
35+
title_font_size=48,
36+
label_font_size=36,
37+
major_label_font_size=32,
38+
legend_font_size=32,
39+
value_font_size=28,
40+
stroke_width=4,
41+
opacity=0.9,
42+
opacity_hover=1.0,
43+
)
44+
45+
# Create line chart
46+
chart = pygal.Line(
47+
width=4800,
48+
height=2700,
49+
style=custom_style,
50+
title="line-loss-training · pygal · pyplots.ai",
51+
x_title="Epoch",
52+
y_title="Cross-Entropy Loss",
53+
show_x_guides=False,
54+
show_y_guides=True,
55+
dots_size=6,
56+
stroke_style={"width": 4},
57+
legend_at_bottom=False,
58+
legend_box_size=24,
59+
margin=50,
60+
x_label_rotation=0,
61+
truncate_label=-1,
62+
show_dots=True,
63+
)
64+
65+
# Set x-axis labels (show every 5th epoch for readability)
66+
chart.x_labels = [str(e) if e % 5 == 0 else "" for e in epochs]
67+
68+
# Add training and validation loss data
69+
chart.add("Training Loss", list(train_loss))
70+
chart.add("Validation Loss", list(val_loss))
71+
72+
# Save as PNG and HTML
73+
chart.render_to_png("plot.png")
74+
chart.render_to_file("plot.html")
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
library: pygal
2+
specification_id: line-loss-training
3+
created: '2025-12-31T00:13:54Z'
4+
updated: '2025-12-31T00:17:57Z'
5+
generated_by: claude-opus-4-5-20251101
6+
workflow_run: 20608711859
7+
issue: 2860
8+
python_version: 3.13.11
9+
library_version: 3.1.0
10+
preview_url: https://storage.googleapis.com/pyplots-images/plots/line-loss-training/pygal/plot.png
11+
preview_thumb: https://storage.googleapis.com/pyplots-images/plots/line-loss-training/pygal/plot_thumb.png
12+
preview_html: https://storage.googleapis.com/pyplots-images/plots/line-loss-training/pygal/plot.html
13+
quality_score: 91
14+
review:
15+
strengths:
16+
- Excellent demonstration of overfitting pattern with training loss continuing to
17+
decrease while validation loss increases after epoch ~25
18+
- Clean, readable code following KISS principles with proper random seed
19+
- 'Appropriate use of Python brand colors (blue #306998, yellow #FFD43B) for visual
20+
distinction'
21+
- Good font sizing and spacing for 4800x2700 canvas with customized Style
22+
- Y-axis label specifies Cross-Entropy Loss as recommended in specification
23+
weaknesses:
24+
- Legend positioned outside plot area in top-left corner appears slightly disconnected
25+
from the chart
26+
- 'Optional feature from spec not implemented: marking the epoch with minimum validation
27+
loss (optimal stopping point)'
28+
- Grid only shows horizontal lines; vertical guides disabled which reduces readability
29+
for epoch identification

0 commit comments

Comments
 (0)