Skip to content

Commit 9789951

Browse files
feat(altair): implement box-horizontal (#2573)
## Implementation: `box-horizontal` - altair Implements the **altair** version of `box-horizontal`. **File:** `plots/box-horizontal/implementations/altair.py` --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/pyplots/actions/runs/20593349773)* --------- 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 dcfe2aa commit 9789951

2 files changed

Lines changed: 93 additions & 0 deletions

File tree

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
""" pyplots.ai
2+
box-horizontal: Horizontal Box Plot
3+
Library: altair 6.0.0 | Python 3.13.11
4+
Quality: 92/100 | Created: 2025-12-30
5+
"""
6+
7+
import altair as alt
8+
import numpy as np
9+
import pandas as pd
10+
11+
12+
# Data - Response times by service type
13+
np.random.seed(42)
14+
15+
data = []
16+
# Create distributions with different characteristics
17+
distributions = {
18+
"Database Query": (120, 40, 5), # mean, std, n_outliers
19+
"API Gateway": (85, 25, 3),
20+
"Authentication": (45, 15, 2),
21+
"File Storage": (200, 60, 4),
22+
"Cache Lookup": (15, 8, 2),
23+
"Email Service": (150, 50, 3),
24+
}
25+
26+
for service, (mean, std, n_outliers) in distributions.items():
27+
# Main distribution
28+
values = np.random.normal(mean, std, 50)
29+
values = np.clip(values, 5, None) # No negative response times
30+
# Add some outliers
31+
outliers = np.random.uniform(mean + 3 * std, mean + 5 * std, n_outliers)
32+
all_values = np.concatenate([values, outliers])
33+
for v in all_values:
34+
data.append({"Service": service, "Response Time (ms)": v})
35+
36+
df = pd.DataFrame(data)
37+
38+
# Sort by median for easier comparison
39+
medians = df.groupby("Service")["Response Time (ms)"].median().sort_values()
40+
df["Service"] = pd.Categorical(df["Service"], categories=medians.index, ordered=True)
41+
42+
# Create horizontal box plot
43+
chart = (
44+
alt.Chart(df)
45+
.mark_boxplot(
46+
box=alt.MarkConfig(color="#306998"),
47+
median=alt.MarkConfig(color="#FFD43B", size=3),
48+
outliers=alt.MarkConfig(color="#306998", size=80),
49+
ticks=alt.MarkConfig(color="#306998"),
50+
rule=alt.MarkConfig(color="#306998"),
51+
)
52+
.encode(
53+
x=alt.X("Response Time (ms):Q", title="Response Time (ms)", scale=alt.Scale(zero=False)),
54+
y=alt.Y("Service:N", title="Service Type", sort=list(medians.index)),
55+
tooltip=["Service:N", "Response Time (ms):Q"],
56+
)
57+
.properties(
58+
width=1400, height=800, title=alt.Title("box-horizontal · altair · pyplots.ai", fontSize=28, anchor="middle")
59+
)
60+
.configure_axis(labelFontSize=18, titleFontSize=22, labelLimit=300)
61+
.configure_view(strokeWidth=0)
62+
)
63+
64+
# Save as PNG and HTML
65+
chart.save("plot.png", scale_factor=3.0)
66+
chart.save("plot.html")
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
library: altair
2+
specification_id: box-horizontal
3+
created: '2025-12-30T09:31:33Z'
4+
updated: '2025-12-30T09:40:56Z'
5+
generated_by: claude-opus-4-5-20251101
6+
workflow_run: 20593349773
7+
issue: 0
8+
python_version: 3.13.11
9+
library_version: 6.0.0
10+
preview_url: https://storage.googleapis.com/pyplots-images/plots/box-horizontal/altair/plot.png
11+
preview_thumb: https://storage.googleapis.com/pyplots-images/plots/box-horizontal/altair/plot_thumb.png
12+
preview_html: https://storage.googleapis.com/pyplots-images/plots/box-horizontal/altair/plot.html
13+
quality_score: 92
14+
review:
15+
strengths:
16+
- Excellent data design with 6 service types showing varied distributions, outliers,
17+
and realistic response time ranges
18+
- Categories sorted by median value for easier comparison as recommended in spec
19+
- Clean implementation with proper Altair encoding types (Q for quantitative, N
20+
for nominal)
21+
- Good customization of box plot components (box color, median color, outlier styling)
22+
- Proper title format following pyplots.ai convention
23+
weaknesses:
24+
- Missing grid lines which could help readers trace values across the wide x-axis
25+
- Could leverage Altair interactive() method for tooltip exploration in the HTML
26+
output
27+
- Slight excess whitespace on right side due to outlier-extended scale

0 commit comments

Comments
 (0)