Skip to content

Commit 62756f7

Browse files
feat(pygal): implement box-horizontal (#2590)
## Implementation: `box-horizontal` - pygal Implements the **pygal** version of `box-horizontal`. **File:** `plots/box-horizontal/implementations/pygal.py` --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/pyplots/actions/runs/20593351461)* --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1 parent a5ee8a2 commit 62756f7

2 files changed

Lines changed: 108 additions & 0 deletions

File tree

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
""" pyplots.ai
2+
box-horizontal: Horizontal Box Plot
3+
Library: pygal 3.1.0 | Python 3.13.11
4+
Quality: 68/100 | Created: 2025-12-30
5+
"""
6+
7+
import numpy as np
8+
import pygal
9+
from pygal.style import Style
10+
11+
12+
# Create HorizontalBox dynamically (pygal doesn't include it natively)
13+
# This uses pygal's standard mixin pattern for horizontal chart variants
14+
HorizontalBox = type("HorizontalBox", (pygal.graph.horizontal.HorizontalGraph, pygal.graph.box.Box), {})
15+
16+
# Data - Response times for different service types (in milliseconds)
17+
np.random.seed(42)
18+
categories = ["Database Query", "API Gateway", "Authentication", "File Upload", "Image Processing"]
19+
data = {
20+
"Database Query": np.random.lognormal(3.5, 0.6, 80),
21+
"API Gateway": np.random.lognormal(3.2, 0.4, 80),
22+
"Authentication": np.random.lognormal(3.8, 0.5, 80),
23+
"File Upload": np.random.lognormal(4.2, 0.7, 80),
24+
"Image Processing": np.random.lognormal(4.5, 0.6, 80),
25+
}
26+
27+
# Add outliers with more moderate values to avoid excessive whitespace
28+
data["Database Query"] = np.append(data["Database Query"], [180, 220, 280])
29+
data["File Upload"] = np.append(data["File Upload"], [350, 420])
30+
data["Image Processing"] = np.append(data["Image Processing"], [450, 520, 580])
31+
32+
# Custom style using PyPlots colors - scaled for 4800x2700 canvas
33+
custom_style = Style(
34+
background="white",
35+
plot_background="white",
36+
foreground="#333333",
37+
foreground_strong="#333333",
38+
foreground_subtle="#666666",
39+
colors=("#306998", "#FFD43B", "#4CAF50", "#FF5722", "#9C27B0"),
40+
title_font_size=60,
41+
label_font_size=40,
42+
major_label_font_size=36,
43+
legend_font_size=36,
44+
value_font_size=32,
45+
)
46+
47+
# Create horizontal box chart with category labels displayed on y-axis
48+
chart = HorizontalBox(
49+
width=4800,
50+
height=2700,
51+
style=custom_style,
52+
title="box-horizontal · pygal · pyplots.ai",
53+
x_title="Response Time (ms)",
54+
show_legend=True,
55+
legend_at_bottom=True,
56+
legend_at_bottom_columns=5,
57+
legend_box_size=30,
58+
show_y_guides=True,
59+
show_x_guides=False,
60+
margin=50,
61+
margin_left=400,
62+
margin_bottom=200,
63+
spacing=60,
64+
box_mode="tukey",
65+
truncate_label=-1,
66+
truncate_legend=-1,
67+
dots_size=8,
68+
)
69+
70+
# Set category labels on y-axis (in horizontal mode, x_labels display on the y-axis)
71+
chart.x_labels = categories
72+
73+
# Add data for each category (legend entries match the x_labels for cross-referencing)
74+
for category in categories:
75+
chart.add(category, data[category].tolist())
76+
77+
# Save outputs
78+
chart.render_to_file("plot.html")
79+
chart.render_to_png("plot.png")
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
library: pygal
2+
specification_id: box-horizontal
3+
created: '2025-12-30T09:34:54Z'
4+
updated: '2025-12-30T10:00:38Z'
5+
generated_by: claude-opus-4-5-20251101
6+
workflow_run: 20593351461
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/box-horizontal/pygal/plot.png
11+
preview_thumb: https://storage.googleapis.com/pyplots-images/plots/box-horizontal/pygal/plot_thumb.png
12+
preview_html: https://storage.googleapis.com/pyplots-images/plots/box-horizontal/pygal/plot.html
13+
quality_score: 68
14+
review:
15+
strengths:
16+
- Creative solution using dynamic class creation to achieve horizontal box plot
17+
in pygal
18+
- Excellent real-world scenario (service response times)
19+
- Good use of pygal custom Style system with appropriate font sizes for 4800x2700
20+
canvas
21+
- Proper use of Tukey box mode for statistical accuracy
22+
- Clean colorblind-safe color palette
23+
weaknesses:
24+
- Category labels are NOT displayed on the y-axis - they only appear in the legend
25+
at bottom, which defeats the purpose of a horizontal box plot
26+
- Excessive whitespace on right side - x-axis extends to 3200ms but data only reaches
27+
~1800ms, wasting ~40% of plot width
28+
- Outlier dots are very small and difficult to see against the white background
29+
- Legend is redundant when it should complement y-axis labels, not replace them

0 commit comments

Comments
 (0)