Skip to content

Commit 2c1193e

Browse files
feat(plotnine): implement violin-box (#2684)
## Implementation: `violin-box` - plotnine Implements the **plotnine** version of `violin-box`. **File:** `plots/violin-box/implementations/plotnine.py` --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/pyplots/actions/runs/20595340834)* --------- 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 690b390 commit 2c1193e

2 files changed

Lines changed: 87 additions & 0 deletions

File tree

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
""" pyplots.ai
2+
violin-box: Violin Plot with Embedded Box Plot
3+
Library: plotnine 0.15.2 | Python 3.13.11
4+
Quality: 93/100 | Created: 2025-12-30
5+
"""
6+
7+
import numpy as np
8+
import pandas as pd
9+
from plotnine import aes, element_text, geom_boxplot, geom_violin, ggplot, labs, scale_fill_manual, theme, theme_minimal
10+
11+
12+
# Data
13+
np.random.seed(42)
14+
n_per_group = 80
15+
16+
# Create groups with different distributions
17+
data = pd.DataFrame(
18+
{
19+
"Value": np.concatenate(
20+
[
21+
np.random.normal(55, 10, n_per_group), # Group A: normal
22+
np.random.exponential(8, n_per_group) + 35, # Group B: right-skewed
23+
np.concatenate(
24+
[ # Group C: bimodal
25+
np.random.normal(40, 5, n_per_group // 2),
26+
np.random.normal(65, 5, n_per_group // 2),
27+
]
28+
),
29+
np.random.uniform(30, 70, n_per_group), # Group D: uniform
30+
]
31+
),
32+
"Group": ["Product A"] * n_per_group
33+
+ ["Product B"] * n_per_group
34+
+ ["Product C"] * n_per_group
35+
+ ["Product D"] * n_per_group,
36+
}
37+
)
38+
39+
# Colors: Python Blue and Yellow plus complementary colors
40+
colors = ["#306998", "#FFD43B", "#6A9BC9", "#D4A84B"]
41+
42+
# Plot
43+
plot = (
44+
ggplot(data, aes(x="Group", y="Value", fill="Group"))
45+
+ geom_violin(alpha=0.7, color="#333333", size=0.5, width=0.9)
46+
+ geom_boxplot(width=0.15, alpha=0.9, color="#333333", fill="white", size=0.5, outlier_size=3)
47+
+ scale_fill_manual(values=colors)
48+
+ labs(title="violin-box · plotnine · pyplots.ai", x="Product Category", y="Customer Satisfaction Score")
49+
+ theme_minimal()
50+
+ theme(
51+
figure_size=(16, 9),
52+
text=element_text(size=14),
53+
axis_title=element_text(size=20),
54+
axis_text=element_text(size=16),
55+
plot_title=element_text(size=24),
56+
legend_position="none",
57+
)
58+
)
59+
60+
# Save
61+
plot.save("plot.png", dpi=300, verbose=False)
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
library: plotnine
2+
specification_id: violin-box
3+
created: '2025-12-30T11:27:24Z'
4+
updated: '2025-12-30T11:36:46Z'
5+
generated_by: claude-opus-4-5-20251101
6+
workflow_run: 20595340834
7+
issue: 0
8+
python_version: 3.13.11
9+
library_version: 0.15.2
10+
preview_url: https://storage.googleapis.com/pyplots-images/plots/violin-box/plotnine/plot.png
11+
preview_thumb: https://storage.googleapis.com/pyplots-images/plots/violin-box/plotnine/plot_thumb.png
12+
preview_html: null
13+
quality_score: 93
14+
review:
15+
strengths:
16+
- Excellent data design showing four distinct distribution types (normal, right-skewed
17+
with outliers, bimodal, uniform)
18+
- Clean layering of geom_violin and geom_boxplot demonstrating plotnine grammar
19+
of graphics
20+
- Good color palette with Python-themed colors that are colorblind-accessible
21+
- Perfect title format and professional appearance
22+
- Outliers visible in Product B demonstrating complete statistical representation
23+
weaknesses:
24+
- Does not showcase plotnine-specific features beyond basic geoms (could use faceting,
25+
stat_summary, or position adjustments)
26+
- Axis labels lack units (e.g., Score (points) or Score (0-100))

0 commit comments

Comments
 (0)