Skip to content

Commit 2f7efd1

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

2 files changed

Lines changed: 90 additions & 0 deletions

File tree

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
""" pyplots.ai
2+
histogram-stepwise: Step Histogram
3+
Library: letsplot 4.8.2 | Python 3.13.11
4+
Quality: 92/100 | Created: 2025-12-30
5+
"""
6+
7+
import numpy as np
8+
import pandas as pd
9+
from lets_plot import * # noqa: F403, F401
10+
11+
12+
LetsPlot.setup_html()
13+
14+
# Data - Generate two distributions for comparison (temperature readings)
15+
np.random.seed(42)
16+
morning_temps = np.random.normal(loc=18, scale=4, size=500) # Morning temperatures (°C)
17+
afternoon_temps = np.random.normal(loc=26, scale=5, size=500) # Afternoon temperatures (°C)
18+
19+
# Compute histogram bins manually for step representation
20+
bins = 30
21+
all_data = np.concatenate([morning_temps, afternoon_temps])
22+
bin_edges = np.linspace(all_data.min(), all_data.max(), bins + 1)
23+
24+
# Calculate histogram counts for each distribution
25+
morning_counts, _ = np.histogram(morning_temps, bins=bin_edges)
26+
afternoon_counts, _ = np.histogram(afternoon_temps, bins=bin_edges)
27+
28+
# Create step data: duplicate each point for step appearance
29+
# For step histogram, we need x values at bin edges and corresponding y values
30+
step_data = []
31+
for counts, label in [(morning_counts, "Morning"), (afternoon_counts, "Afternoon")]:
32+
for i in range(len(counts)):
33+
# Left edge of bin at count level
34+
step_data.append({"x": bin_edges[i], "y": counts[i], "period": label})
35+
# Right edge of bin at count level
36+
step_data.append({"x": bin_edges[i + 1], "y": counts[i], "period": label})
37+
38+
df_step = pd.DataFrame(step_data)
39+
40+
# Plot - Step histogram using geom_line (outline only, no fill)
41+
plot = (
42+
ggplot(df_step, aes(x="x", y="y", color="period"))
43+
+ geom_line(size=2.5)
44+
+ scale_color_manual(values=["#306998", "#FFD43B"])
45+
+ labs(x="Temperature (°C)", y="Frequency", title="histogram-stepwise · letsplot · pyplots.ai", color="Time Period")
46+
+ theme_minimal()
47+
+ theme(
48+
axis_title=element_text(size=20),
49+
axis_text=element_text(size=16),
50+
plot_title=element_text(size=24),
51+
legend_title=element_text(size=18),
52+
legend_text=element_text(size=16),
53+
legend_position="right",
54+
panel_grid_major=element_line(color="#CCCCCC", size=0.5),
55+
panel_grid_minor=element_blank(),
56+
)
57+
+ ggsize(1600, 900)
58+
)
59+
60+
# Save PNG (scale=3 gives 4800x2700)
61+
ggsave(plot, "plot.png", path=".", scale=3)
62+
63+
# Save HTML for interactivity
64+
ggsave(plot, "plot.html", path=".")
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
library: letsplot
2+
specification_id: histogram-stepwise
3+
created: '2025-12-30T11:24:54Z'
4+
updated: '2025-12-30T11:36:25Z'
5+
generated_by: claude-opus-4-5-20251101
6+
workflow_run: 20595340386
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-stepwise/letsplot/plot.png
11+
preview_thumb: https://storage.googleapis.com/pyplots-images/plots/histogram-stepwise/letsplot/plot_thumb.png
12+
preview_html: https://storage.googleapis.com/pyplots-images/plots/histogram-stepwise/letsplot/plot.html
13+
quality_score: 92
14+
review:
15+
strengths:
16+
- Excellent implementation of step histogram concept using manual bin calculation
17+
and geom_line
18+
- Two overlaid distributions clearly demonstrate the key use case of comparing distributions
19+
without visual overlap
20+
- Strong color contrast between blue and yellow that is colorblind-accessible
21+
- Proper use of ggplot grammar with clean, readable code structure
22+
- Realistic temperature comparison scenario that makes immediate sense
23+
- Text sizing and layout are publication-quality
24+
weaknesses:
25+
- Could leverage lets-plot interactive tooltip features for the HTML output
26+
- Legend title is slightly generic compared to a more descriptive label

0 commit comments

Comments
 (0)