Skip to content

Commit 263e16a

Browse files
feat(pygal): implement cat-strip (#2758)
## Implementation: `cat-strip` - pygal Implements the **pygal** version of `cat-strip`. **File:** `plots/cat-strip/implementations/pygal.py` --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/pyplots/actions/runs/20601059545)* --------- 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 137f23c commit 263e16a

2 files changed

Lines changed: 114 additions & 0 deletions

File tree

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
""" pyplots.ai
2+
cat-strip: Categorical Strip Plot
3+
Library: pygal 3.1.0 | Python 3.13.11
4+
Quality: 91/100 | Created: 2025-12-30
5+
"""
6+
7+
import numpy as np
8+
import pygal
9+
from pygal.style import Style
10+
11+
12+
# Data - Performance scores across different departments
13+
np.random.seed(42)
14+
categories = ["Sales", "Engineering", "Marketing", "Support"]
15+
n_per_category = 25
16+
17+
# Generate realistic performance scores for each department
18+
data = {
19+
"Sales": np.random.normal(75, 12, n_per_category),
20+
"Engineering": np.random.normal(82, 8, n_per_category),
21+
"Marketing": np.random.normal(70, 15, n_per_category),
22+
"Support": np.random.normal(78, 10, n_per_category),
23+
}
24+
25+
# Clip to realistic range (0-100)
26+
for cat in data:
27+
data[cat] = np.clip(data[cat], 40, 100)
28+
29+
# Create jittered x-positions for strip plot effect
30+
jitter_width = 0.3
31+
points_by_category = {}
32+
for i, cat in enumerate(categories):
33+
x_jitter = np.random.uniform(-jitter_width, jitter_width, n_per_category)
34+
x_positions = i + x_jitter
35+
points_by_category[cat] = list(zip(x_positions, data[cat], strict=False))
36+
37+
# Custom style for large canvas
38+
custom_style = Style(
39+
background="white",
40+
plot_background="white",
41+
foreground="#333333",
42+
foreground_strong="#333333",
43+
foreground_subtle="#666666",
44+
colors=("#306998", "#FFD43B", "#4CAF50", "#E91E63"),
45+
title_font_size=72,
46+
label_font_size=48,
47+
major_label_font_size=42,
48+
legend_font_size=42,
49+
value_font_size=36,
50+
tooltip_font_size=36,
51+
)
52+
53+
# Create custom x-label formatter to show category names
54+
x_label_map = {0: "Sales", 1: "Engineering", 2: "Marketing", 3: "Support"}
55+
56+
# Create XY chart (scatter plot)
57+
chart = pygal.XY(
58+
width=4800,
59+
height=2700,
60+
style=custom_style,
61+
title="cat-strip · pygal · pyplots.ai",
62+
x_title="Department",
63+
y_title="Performance Score",
64+
show_legend=True,
65+
legend_at_bottom=True,
66+
legend_at_bottom_columns=4,
67+
stroke=False,
68+
dots_size=12,
69+
show_x_guides=False,
70+
show_y_guides=True,
71+
x_label_rotation=0,
72+
range=(35, 105),
73+
xrange=(-0.5, 3.5),
74+
explicit_size=True,
75+
print_values=False,
76+
x_value_formatter=lambda x: x_label_map.get(int(round(x)), ""),
77+
)
78+
79+
# Add data for each category as separate series
80+
for cat in categories:
81+
chart.add(cat, points_by_category[cat])
82+
83+
# Set x-axis labels at category positions (integers that will be formatted)
84+
chart.x_labels = [0, 1, 2, 3]
85+
chart.x_labels_major = [0, 1, 2, 3]
86+
87+
# Render to PNG and HTML
88+
chart.render_to_png("plot.png")
89+
chart.render_to_file("plot.html")
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
library: pygal
2+
specification_id: cat-strip
3+
created: '2025-12-30T16:30:49Z'
4+
updated: '2025-12-30T16:54:25Z'
5+
generated_by: claude-opus-4-5-20251101
6+
workflow_run: 20601059545
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/cat-strip/pygal/plot.png
11+
preview_thumb: https://storage.googleapis.com/pyplots-images/plots/cat-strip/pygal/plot_thumb.png
12+
preview_html: https://storage.googleapis.com/pyplots-images/plots/cat-strip/pygal/plot.html
13+
quality_score: 91
14+
review:
15+
strengths:
16+
- Excellent jitter implementation using XY chart with calculated x-positions
17+
- Clean, professional color scheme with four distinct, accessible colors
18+
- Proper title format following pyplots.ai convention
19+
- Realistic business context (department performance scores)
20+
- Good distribution variation showing different spreads and an outlier
21+
- Well-configured custom Style with appropriate font sizes for large canvas
22+
weaknesses:
23+
- Axis labels lack units (could be "Performance Score (%)" if percentages)
24+
- Grid could be slightly more subtle (current alpha via style is acceptable but
25+
could improve)

0 commit comments

Comments
 (0)