Skip to content

Commit a83ca98

Browse files
feat(letsplot): implement histogram-density (#2487)
## Implementation: `histogram-density` - letsplot Implements the **letsplot** version of `histogram-density`. **File:** `plots/histogram-density/implementations/letsplot.py` --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/pyplots/actions/runs/20584334205)* --------- 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 bd1b954 commit a83ca98

2 files changed

Lines changed: 86 additions & 0 deletions

File tree

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
""" pyplots.ai
2+
histogram-density: Density Histogram
3+
Library: letsplot 4.8.2 | Python 3.13.11
4+
Quality: 91/100 | Created: 2025-12-29
5+
"""
6+
7+
import numpy as np
8+
import pandas as pd
9+
from lets_plot import *
10+
from scipy import stats
11+
12+
13+
LetsPlot.setup_html()
14+
15+
# Data - Test scores with normal-like distribution
16+
np.random.seed(42)
17+
scores = np.concatenate(
18+
[
19+
np.random.normal(72, 8, 300), # Main group
20+
np.random.normal(88, 5, 100), # High performers
21+
]
22+
)
23+
# Clip to realistic test score range
24+
scores = np.clip(scores, 0, 100)
25+
26+
# Create DataFrame
27+
df = pd.DataFrame({"score": scores})
28+
29+
# Create theoretical normal distribution for overlay
30+
x_range = np.linspace(scores.min() - 5, scores.max() + 5, 200)
31+
# Fit normal distribution to data
32+
mu, sigma = stats.norm.fit(scores)
33+
y_pdf = stats.norm.pdf(x_range, mu, sigma)
34+
df_pdf = pd.DataFrame({"x": x_range, "y": y_pdf})
35+
36+
# Create density histogram with KDE overlay
37+
plot = (
38+
ggplot()
39+
+ geom_histogram(
40+
aes(x="score", y="..density.."), data=df, bins=25, fill="#306998", color="white", alpha=0.7, size=0.5
41+
)
42+
+ geom_line(aes(x="x", y="y"), data=df_pdf, color="#FFD43B", size=2.5)
43+
+ labs(x="Test Score", y="Density", title="histogram-density · letsplot · pyplots.ai")
44+
+ theme_minimal()
45+
+ theme(
46+
plot_title=element_text(size=24),
47+
axis_title=element_text(size=20),
48+
axis_text=element_text(size=16),
49+
panel_grid_major=element_line(color="#CCCCCC", size=0.3),
50+
)
51+
+ ggsize(1600, 900)
52+
)
53+
54+
# Save as PNG (scale 3x = 4800 x 2700 px)
55+
ggsave(plot, "plot.png", path=".", scale=3)
56+
57+
# Save as HTML for interactivity
58+
ggsave(plot, "plot.html", path=".")
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
library: letsplot
2+
specification_id: histogram-density
3+
created: '2025-12-29T22:53:39Z'
4+
updated: '2025-12-29T23:01:40Z'
5+
generated_by: claude-opus-4-5-20251101
6+
workflow_run: 20584334205
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/histogram-density/letsplot/plot.png
11+
preview_thumb: https://storage.googleapis.com/pyplots-images/plots/histogram-density/letsplot/plot_thumb.png
12+
preview_html: https://storage.googleapis.com/pyplots-images/plots/histogram-density/letsplot/plot.html
13+
quality_score: 91
14+
review:
15+
strengths:
16+
- Excellent implementation of density histogram with proper ..density.. stat transformation
17+
- Clean addition of fitted normal distribution PDF overlay using scipy.stats
18+
- 'Appropriate color scheme (#306998 blue bars, #FFD43B yellow line) with good contrast'
19+
- Proper use of lets-plot ggplot2-like grammar with theme customization
20+
- Bimodal data distribution effectively demonstrates density normalization concept
21+
- Correct figure sizing (1600x900 base with scale=3) and text sizing per library
22+
guidelines
23+
weaknesses:
24+
- Axis labels lack units (could specify Test Score points or Density probability
25+
per unit)
26+
- A legend explaining the yellow line as Fitted Normal Distribution would add clarity
27+
- Could leverage more distinctive lets-plot features like scale_fill_* or tooltip
28+
configuration

0 commit comments

Comments
 (0)