Skip to content

Commit 5d97c0a

Browse files
feat(letsplot): implement contour-density (#2594)
## Implementation: `contour-density` - letsplot Implements the **letsplot** version of `contour-density`. **File:** `plots/contour-density/implementations/letsplot.py` --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/pyplots/actions/runs/20593405154)* --------- 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 2fe1594 commit 5d97c0a

2 files changed

Lines changed: 85 additions & 0 deletions

File tree

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
""" pyplots.ai
2+
contour-density: Density Contour Plot
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 *
10+
11+
12+
LetsPlot.setup_html()
13+
14+
# Data - two clusters with different spreads for bivariate distribution
15+
np.random.seed(42)
16+
17+
# Cluster 1: Dense core cluster (temperature measurements)
18+
n1 = 400
19+
x1 = np.random.normal(loc=22, scale=3, size=n1)
20+
y1 = np.random.normal(loc=55, scale=8, size=n1)
21+
22+
# Cluster 2: More diffuse cluster
23+
n2 = 300
24+
x2 = np.random.normal(loc=32, scale=5, size=n2)
25+
y2 = np.random.normal(loc=75, scale=10, size=n2)
26+
27+
# Cluster 3: Small dense cluster
28+
n3 = 150
29+
x3 = np.random.normal(loc=15, scale=2, size=n3)
30+
y3 = np.random.normal(loc=80, scale=5, size=n3)
31+
32+
# Combine clusters
33+
x = np.concatenate([x1, x2, x3])
34+
y = np.concatenate([y1, y2, y3])
35+
36+
df = pd.DataFrame({"temperature": x, "humidity": y})
37+
38+
# Plot - density contour with scatter overlay for context
39+
plot = (
40+
ggplot(df, aes(x="temperature", y="humidity"))
41+
+ geom_density2d(color="#306998", size=1.2, bins=10)
42+
+ geom_point(color="#FFD43B", alpha=0.3, size=2)
43+
+ labs(x="Temperature (°C)", y="Relative Humidity (%)", title="contour-density · letsplot · pyplots.ai")
44+
+ theme_minimal()
45+
+ theme(
46+
axis_title=element_text(size=20),
47+
axis_text=element_text(size=16),
48+
plot_title=element_text(size=24),
49+
panel_grid=element_line(color="#888888", size=0.3),
50+
panel_grid_minor=element_blank(),
51+
)
52+
+ ggsize(1600, 900)
53+
)
54+
55+
# Save as PNG (scale 3x for 4800 × 2700 px)
56+
ggsave(plot, "plot.png", path=".", scale=3)
57+
58+
# Save as HTML for interactive version
59+
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: contour-density
3+
created: '2025-12-30T09:37:09Z'
4+
updated: '2025-12-30T09:47:24Z'
5+
generated_by: claude-opus-4-5-20251101
6+
workflow_run: 20593405154
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/contour-density/letsplot/plot.png
11+
preview_thumb: https://storage.googleapis.com/pyplots-images/plots/contour-density/letsplot/plot_thumb.png
12+
preview_html: https://storage.googleapis.com/pyplots-images/plots/contour-density/letsplot/plot.html
13+
quality_score: 92
14+
review:
15+
strengths:
16+
- Excellent visualization of three distinct density clusters with clear concentric
17+
contour lines
18+
- Good use of scatter overlay with low alpha providing context without overwhelming
19+
the contours
20+
- Proper ggplot2-style grammar with geom_density2d following lets-plot conventions
21+
- Axis labels include appropriate units (°C, %) and are descriptive
22+
- 'Title follows the exact required format: spec-id · library · pyplots.ai'
23+
- Realistic temperature/humidity scenario with sensible data ranges
24+
weaknesses:
25+
- Scatter point alpha could be slightly lower (0.2) for better contour visibility
26+
in dense areas

0 commit comments

Comments
 (0)