Ridgeline Plot

Sleep Score Distribution by Age

Health metrics with calming purple-blue gradient

Output
Sleep Score Distribution by Age
Python
import matplotlib.pyplot as plt
import numpy as np
from scipy import stats

np.random.seed(555)

ages = ['18-25', '26-35', '36-45', '46-55', '56-65', '65+']
colors = ['#4927F5', '#5314E6', '#276CF5', '#27D3F5', '#F527B0', '#F5276C']

data = {
    '18-25': np.random.beta(4, 3, 500) * 50 + 50,
    '26-35': np.random.beta(5, 4, 500) * 50 + 45,
    '36-45': np.random.beta(4, 4, 500) * 50 + 40,
    '46-55': np.random.beta(4, 5, 500) * 50 + 35,
    '56-65': np.random.beta(3, 4, 500) * 50 + 40,
    '65+': np.random.beta(3, 5, 500) * 50 + 35
}

fig, ax = plt.subplots(figsize=(12, 8), facecolor='#ffffff')
ax.set_facecolor('#ffffff')

overlap = 1.6
x_range = np.linspace(20, 100, 300)

for i, (age, score) in enumerate(data.items()):
    kde = stats.gaussian_kde(score, bw_method=0.3)
    y = kde(x_range) * 3.5
    baseline = i * overlap
    
    ax.fill_between(x_range, baseline, y + baseline, alpha=0.7, color=colors[i])
    ax.plot(x_range, y + baseline, color=colors[i], linewidth=2.5)
    
    ax.text(18, baseline + 0.12, age, fontsize=11, color='#1f2937',
            ha='right', va='bottom', fontweight='600')

ax.set_xlim(10, 100)
ax.set_ylim(-0.3, len(ages) * overlap + 1.8)
ax.set_xlabel('Sleep Quality Score', fontsize=12, color='#374151', fontweight='500')
ax.set_title('Sleep Score Distribution by Age', fontsize=16, color='#1f2937', fontweight='bold', pad=20)

ax.tick_params(axis='x', colors='#374151', labelsize=10)
ax.tick_params(axis='y', left=False, labelleft=False)
ax.spines['bottom'].set_color('#e5e7eb')
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.spines['left'].set_visible(False)

plt.tight_layout()
plt.show()
Library

Matplotlib

Category

Statistical

Did this help you?

Support PyLucid to keep it free & growing

Support