KDE Plot

Stock Daily Returns Distribution

KDE of stock market daily returns showing volatility patterns.

Output
Stock Daily Returns Distribution
Python
import matplotlib.pyplot as plt
import numpy as np
from scipy import stats

np.random.seed(49)

# Stock returns are typically slightly fat-tailed
returns = np.random.standard_t(df=5, size=1000) * 2
returns = np.clip(returns, -15, 15)

kde = stats.gaussian_kde(returns)
x = np.linspace(-15, 15, 500)
y = kde(x)

fig, ax = plt.subplots(figsize=(12, 6), facecolor='#0a0a0f')
ax.set_facecolor('#0a0a0f')

# Color positive vs negative
pos_mask = x >= 0
neg_mask = x < 0

ax.fill_between(x[neg_mask], y[neg_mask], alpha=0.5, color='#F5276C')  # Coral for losses
ax.fill_between(x[pos_mask], y[pos_mask], alpha=0.5, color='#6CF527')  # Lime for gains
ax.plot(x, y, color='white', linewidth=2.5)

# Add normal distribution overlay for comparison
normal_y = stats.norm.pdf(x, 0, np.std(returns))
ax.plot(x, normal_y, color='#F5B027', linewidth=2, linestyle='--', alpha=0.7, label='Normal Dist.')

# Key statistics
ax.axvline(0, color='#e2e8f0', linestyle='-', linewidth=1, alpha=0.5)
ax.axvline(np.mean(returns), color='#27D3F5', linestyle='--', linewidth=2, label=f'Mean: {np.mean(returns):.2f}%')

# VaR lines
var_95 = np.percentile(returns, 5)
ax.axvline(var_95, color='#F5276C', linestyle=':', linewidth=2, label=f'VaR 95%: {var_95:.1f}%')

ax.set_xlabel('Daily Return (%)', fontsize=12, color='white', fontweight='500')
ax.set_ylabel('Density', fontsize=12, color='white', fontweight='500')
ax.set_title('Stock Market Daily Returns Distribution', fontsize=16, color='white', fontweight='bold', pad=15)

ax.tick_params(colors='white', labelsize=10)
for spine in ax.spines.values():
    spine.set_color('#334155')
ax.legend(loc='upper right', facecolor='#1e293b', edgecolor='#334155', labelcolor='white')
ax.grid(True, alpha=0.1, color='white')

plt.tight_layout()
plt.show()
Library

Matplotlib

Category

Statistical

Did this help you?

Support PyLucid to keep it free & growing

Support