Skip to content

Commit 345dee1

Browse files
feat(plotly): implement ridgeline-basic (#546)
## Summary Implements `ridgeline-basic` for **plotly**. **Parent Issue:** #539 **Base Branch:** `plot/ridgeline-basic` ## Files - `plots/ridgeline-basic/implementations/plotly.py` ## Preview Preview will be uploaded to GCS staging after this workflow completes. Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent 08b50c1 commit 345dee1

File tree

1 file changed

+132
-0
lines changed
  • plots/ridgeline-basic/implementations

1 file changed

+132
-0
lines changed
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
"""
2+
ridgeline-basic: Ridgeline Plot
3+
Library: plotly
4+
"""
5+
6+
import numpy as np
7+
import plotly.graph_objects as go
8+
from scipy import stats
9+
10+
11+
# Data - Monthly temperature readings (simulating seasonal patterns)
12+
np.random.seed(42)
13+
14+
months = [
15+
"January",
16+
"February",
17+
"March",
18+
"April",
19+
"May",
20+
"June",
21+
"July",
22+
"August",
23+
"September",
24+
"October",
25+
"November",
26+
"December",
27+
]
28+
29+
# Generate temperature data with seasonal patterns
30+
month_temps = {
31+
"January": np.random.normal(2, 4, 200),
32+
"February": np.random.normal(4, 4, 200),
33+
"March": np.random.normal(9, 5, 200),
34+
"April": np.random.normal(14, 4, 200),
35+
"May": np.random.normal(18, 4, 200),
36+
"June": np.random.normal(22, 3, 200),
37+
"July": np.random.normal(25, 3, 200),
38+
"August": np.random.normal(24, 3, 200),
39+
"September": np.random.normal(20, 4, 200),
40+
"October": np.random.normal(14, 4, 200),
41+
"November": np.random.normal(8, 4, 200),
42+
"December": np.random.normal(4, 4, 200),
43+
}
44+
45+
# Color palette - gradient from cool to warm colors
46+
colors = [
47+
"#306998", # January - Python Blue
48+
"#3B7BA8",
49+
"#4A8DB5",
50+
"#5E9EC2",
51+
"#7BB0C9",
52+
"#9FC5D4",
53+
"#C4DBDE",
54+
"#E8D5B5",
55+
"#F5C48A",
56+
"#F9A857",
57+
"#F97316", # Orange
58+
"#DC2626", # December - Signal Red
59+
]
60+
61+
# Create figure
62+
fig = go.Figure()
63+
64+
# Calculate KDE for each month and add as filled area
65+
x_range = np.linspace(-15, 40, 300)
66+
spacing = 0.15 # Vertical spacing between ridges
67+
max_density = 0 # Track max density for scaling
68+
69+
# First pass: calculate all KDEs and find max density
70+
kde_results = []
71+
for month in months:
72+
data = month_temps[month]
73+
kde = stats.gaussian_kde(data, bw_method=0.3)
74+
density = kde(x_range)
75+
kde_results.append(density)
76+
max_density = max(max_density, density.max())
77+
78+
# Scale factor for ridge height
79+
scale_factor = spacing * 0.8 / max_density
80+
81+
# Second pass: add traces from bottom to top (reversed for proper layering)
82+
for i, month in enumerate(reversed(months)):
83+
idx = len(months) - 1 - i
84+
density = kde_results[idx] * scale_factor
85+
y_base = idx * spacing
86+
87+
# Create the filled area trace
88+
fig.add_trace(
89+
go.Scatter(
90+
x=np.concatenate([x_range, x_range[::-1]]),
91+
y=np.concatenate([y_base + density, np.full_like(x_range, y_base)]),
92+
fill="toself",
93+
fillcolor=colors[idx],
94+
line={"color": "white", "width": 1.5},
95+
opacity=0.75,
96+
name=month,
97+
hovertemplate=f"<b>{month}</b><br>Temperature: %{{x:.1f}}°C<extra></extra>",
98+
)
99+
)
100+
101+
# Update layout
102+
fig.update_layout(
103+
title={"text": "Monthly Temperature Distribution", "font": {"size": 48}, "x": 0.5, "xanchor": "center"},
104+
xaxis={
105+
"title": {"text": "Temperature (°C)", "font": {"size": 40}},
106+
"tickfont": {"size": 32},
107+
"showgrid": True,
108+
"gridwidth": 1,
109+
"gridcolor": "rgba(128, 128, 128, 0.2)",
110+
"zeroline": False,
111+
"range": [-12, 38],
112+
},
113+
yaxis={
114+
"title": {"text": "Month", "font": {"size": 40}},
115+
"tickfont": {"size": 32},
116+
"tickmode": "array",
117+
"tickvals": [i * spacing for i in range(len(months))],
118+
"ticktext": months,
119+
"showgrid": False,
120+
"zeroline": False,
121+
},
122+
showlegend=False,
123+
template="plotly_white",
124+
margin={"l": 200, "r": 100, "t": 150, "b": 100},
125+
plot_bgcolor="white",
126+
paper_bgcolor="white",
127+
hoverlabel={"font_size": 24},
128+
)
129+
130+
# Save outputs
131+
fig.write_image("plot.png", width=1600, height=900, scale=3)
132+
fig.write_html("plot.html", include_plotlyjs="cdn")

0 commit comments

Comments
 (0)