Skip to content

Commit 2385e57

Browse files
feat(letsplot): implement bar-categorical (#2680)
## Implementation: `bar-categorical` - letsplot Implements the **letsplot** version of `bar-categorical`. **File:** `plots/bar-categorical/implementations/letsplot.py` --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/pyplots/actions/runs/20595340647)* --------- 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 6fb20ff commit 2385e57

2 files changed

Lines changed: 69 additions & 0 deletions

File tree

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
""" pyplots.ai
2+
bar-categorical: Categorical Count Bar Chart
3+
Library: letsplot 4.8.2 | Python 3.13.11
4+
Quality: 91/100 | Created: 2025-12-30
5+
"""
6+
7+
import numpy as np
8+
import pandas as pd
9+
from lets_plot import * # noqa: F403
10+
from lets_plot.export import ggsave as export_ggsave
11+
12+
13+
LetsPlot.setup_html() # noqa: F405
14+
15+
# Data - raw categorical values (counts computed automatically by geom_bar)
16+
np.random.seed(42)
17+
categories = ["Apples", "Bananas", "Oranges", "Grapes", "Mangoes"]
18+
weights = [0.25, 0.20, 0.22, 0.18, 0.15]
19+
n_samples = 200
20+
21+
df = pd.DataFrame({"fruit": np.random.choice(categories, size=n_samples, p=weights)})
22+
23+
# Plot - geom_bar computes counts automatically (no stat='identity')
24+
plot = (
25+
ggplot(df, aes(x="fruit")) # noqa: F405
26+
+ geom_bar(fill="#306998", color="#1a3a54", size=0.5, alpha=0.9) # noqa: F405
27+
+ labs( # noqa: F405
28+
x="Fruit Type", y="Count", title="bar-categorical · letsplot · pyplots.ai"
29+
)
30+
+ ggsize(1600, 900) # noqa: F405
31+
+ theme_minimal() # noqa: F405
32+
+ theme( # noqa: F405
33+
plot_title=element_text(size=24, face="bold"), # noqa: F405
34+
axis_title=element_text(size=20), # noqa: F405
35+
axis_text=element_text(size=16), # noqa: F405
36+
axis_text_x=element_text(angle=0), # noqa: F405
37+
panel_grid_major_x=element_blank(), # noqa: F405
38+
panel_grid_minor=element_blank(), # noqa: F405
39+
)
40+
)
41+
42+
# Save as PNG (scale 3x for 4800x2700 px) and HTML
43+
export_ggsave(plot, filename="plot.png", path=".", scale=3)
44+
export_ggsave(plot, filename="plot.html", path=".")
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
library: letsplot
2+
specification_id: bar-categorical
3+
created: '2025-12-30T11:24:11Z'
4+
updated: '2025-12-30T11:32:01Z'
5+
generated_by: claude-opus-4-5-20251101
6+
workflow_run: 20595340647
7+
issue: 0
8+
python_version: 3.13.11
9+
library_version: 4.8.2
10+
preview_url: https://storage.googleapis.com/pyplots-images/plots/bar-categorical/letsplot/plot.png
11+
preview_thumb: https://storage.googleapis.com/pyplots-images/plots/bar-categorical/letsplot/plot_thumb.png
12+
preview_html: https://storage.googleapis.com/pyplots-images/plots/bar-categorical/letsplot/plot.html
13+
quality_score: 91
14+
review:
15+
strengths:
16+
- Clean implementation following ggplot2 grammar of graphics
17+
- Automatic count computation using geom_bar() without stat=identity
18+
- Well-sized text elements (24pt title, 20pt axis labels, 16pt tick text) following
19+
library guidelines
20+
- Good use of theme_minimal() with appropriate grid customization
21+
- Proper figure sizing (1600x900 with scale=3 for 4800x2700 output)
22+
weaknesses:
23+
- Does not leverage lets-plot interactive features (tooltips, hover effects) that
24+
distinguish it from plotnine
25+
- Data context is generic; could use a more specific real-world scenario

0 commit comments

Comments
 (0)