Violin Plot
Portfolio Volatility Analysis
Daily returns distribution by sector with Value at Risk (VaR) indicators
Output
Python
import matplotlib.pyplot as plt
import numpy as np
# Simulated daily returns by sector
np.random.seed(42)
sectors = ['Tech', 'Healthcare', 'Finance', 'Energy', 'Consumer']
volatility = [0.025, 0.018, 0.022, 0.035, 0.015]
returns = [np.random.normal(0.001, vol, 252) * 100 for vol in volatility]
# Risk colors: green (low) to red (high)
risk_colors = ['#10B981', '#22C55E', '#F59E0B', '#EF4444', '#059669']
sorted_idx = np.argsort(volatility)
# Create figure
fig, ax = plt.subplots(figsize=(12, 7), facecolor='#FAFBFC')
ax.set_facecolor('#FAFBFC')
vp = ax.violinplot(returns, positions=range(len(sectors)), widths=0.75,
showmeans=False, showmedians=False, showextrema=False)
for i, body in enumerate(vp['bodies']):
# Color by volatility
vol_rank = list(sorted_idx).index(i)
color = ['#10B981', '#84CC16', '#F59E0B', '#F97316', '#EF4444'][vol_rank]
body.set_facecolor(color)
body.set_edgecolor('white')
body.set_linewidth(2)
body.set_alpha(0.8)
# Glow effect
path = body.get_paths()[0]
ax.fill(path.vertices[:, 0], path.vertices[:, 1],
color=color, alpha=0.15, zorder=0)
# Add VaR lines (Value at Risk - 5th percentile)
for i, ret in enumerate(returns):
var_5 = np.percentile(ret, 5)
ax.hlines(var_5, i - 0.3, i + 0.3, color='#DC2626', linewidth=2,
linestyle='--', zorder=10)
ax.scatter(i, var_5, c='#DC2626', s=50, zorder=11, marker='v')
# Median
median = np.median(ret)
ax.scatter(i, median, c='white', s=80, zorder=12,
edgecolor='#1F2937', linewidth=2)
# Zero reference line
ax.axhline(0, color='#6B7280', linewidth=1, linestyle='-', alpha=0.5)
# Legend for VaR
ax.plot([], [], color='#DC2626', linestyle='--', linewidth=2,
marker='v', label='VaR 95%')
ax.scatter([], [], c='white', s=80, edgecolor='#1F2937',
linewidth=2, label='Median')
ax.legend(loc='upper right', frameon=True, facecolor='white',
edgecolor='#E5E7EB', fontsize=10)
# Styling
ax.set_xticks(range(len(sectors)))
ax.set_xticklabels(sectors, fontsize=12, fontweight='600')
ax.set_ylabel('Daily Returns (%)', fontsize=12, fontweight='500', color='#374151')
ax.set_ylim(-12, 12)
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.spines['left'].set_color('#E5E7EB')
ax.spines['bottom'].set_color('#E5E7EB')
ax.tick_params(colors='#6B7280', labelsize=10)
ax.yaxis.grid(True, linestyle='--', alpha=0.4, color='#D1D5DB')
plt.tight_layout()
plt.show()
Library
Matplotlib
Category
Statistical
More Violin Plot examples
☕