Skip to content

Commit 9506fae

Browse files
feat(altair): implement scatter-regression-lowess (#2870)
## Implementation: `scatter-regression-lowess` - altair Implements the **altair** version of `scatter-regression-lowess`. **File:** `plots/scatter-regression-lowess/implementations/altair.py` **Parent Issue:** #2855 --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/pyplots/actions/runs/20608462838)* --------- 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 73b65b7 commit 9506fae

2 files changed

Lines changed: 76 additions & 0 deletions

File tree

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
""" pyplots.ai
2+
scatter-regression-lowess: Scatter Plot with LOWESS Regression
3+
Library: altair 6.0.0 | Python 3.13.11
4+
Quality: 91/100 | Created: 2025-12-30
5+
"""
6+
7+
import altair as alt
8+
import numpy as np
9+
import pandas as pd
10+
from statsmodels.nonparametric.smoothers_lowess import lowess
11+
12+
13+
# Data - complex non-linear relationship
14+
np.random.seed(42)
15+
n = 200
16+
x = np.linspace(0, 10, n)
17+
# Non-linear pattern: sine wave with trend and noise
18+
y = 2 * np.sin(x * 0.8) + 0.5 * x + np.random.normal(0, 0.8, n)
19+
20+
# Create DataFrame for scatter points
21+
df = pd.DataFrame({"x": x, "y": y})
22+
23+
# Compute LOWESS smoothed values
24+
lowess_result = lowess(y, x, frac=0.3, return_sorted=True)
25+
df_lowess = pd.DataFrame({"x": lowess_result[:, 0], "y_lowess": lowess_result[:, 1]})
26+
27+
# Scatter points layer
28+
scatter = (
29+
alt.Chart(df)
30+
.mark_point(size=100, opacity=0.6, color="#306998")
31+
.encode(x=alt.X("x:Q", title="Independent Variable (x)"), y=alt.Y("y:Q", title="Dependent Variable (y)"))
32+
)
33+
34+
# LOWESS curve layer
35+
lowess_line = (
36+
alt.Chart(df_lowess).mark_line(strokeWidth=4, color="#FFD43B").encode(x=alt.X("x:Q"), y=alt.Y("y_lowess:Q"))
37+
)
38+
39+
# Combine layers
40+
chart = (
41+
(scatter + lowess_line)
42+
.properties(width=1600, height=900, title=alt.Title("scatter-regression-lowess · altair · pyplots.ai", fontSize=28))
43+
.configure_axis(labelFontSize=18, titleFontSize=22, gridOpacity=0.3)
44+
.configure_view(strokeWidth=0)
45+
)
46+
47+
# Save as PNG and HTML
48+
chart.save("plot.png", scale_factor=3.0)
49+
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: scatter-regression-lowess
3+
created: '2025-12-30T23:52:29Z'
4+
updated: '2025-12-30T23:55:55Z'
5+
generated_by: claude-opus-4-5-20251101
6+
workflow_run: 20608462838
7+
issue: 2855
8+
python_version: 3.13.11
9+
library_version: 6.0.0
10+
preview_url: https://storage.googleapis.com/pyplots-images/plots/scatter-regression-lowess/altair/plot.png
11+
preview_thumb: https://storage.googleapis.com/pyplots-images/plots/scatter-regression-lowess/altair/plot_thumb.png
12+
preview_html: https://storage.googleapis.com/pyplots-images/plots/scatter-regression-lowess/altair/plot.html
13+
quality_score: 91
14+
review:
15+
strengths:
16+
- Excellent visual clarity with properly sized text elements and good color contrast
17+
- LOWESS curve is visually distinct and captures the complex non-linear pattern
18+
smoothly
19+
- Clean, idiomatic Altair code using declarative layer composition
20+
- Proper use of frac=0.3 for balanced smoothness as specified
21+
- Good marker sizing and transparency for the data density (200 points)
22+
- Canvas utilization and layout are well balanced
23+
weaknesses:
24+
- Axis labels are generic rather than having real-world context with units
25+
- No interactive features like tooltips or zoom added despite Altair strength in
26+
interactivity
27+
- Markers use outline style which can be slightly less visible than filled markers

0 commit comments

Comments
 (0)