Violin Plot
Drug Efficacy Clinical Trial
Time to symptom relief distribution across treatment phases
Output
Python
import matplotlib.pyplot as plt
import numpy as np
# Time to symptom relief (hours)
np.random.seed(42)
treatments = ['Placebo', 'Standard\nCare', 'New Drug\n(Phase II)', 'New Drug\n(Phase III)']
relief_times = [
np.random.exponential(24, 200) + 12, # Placebo - slow
np.random.gamma(4, 4, 200) + 6, # Standard - moderate
np.random.gamma(6, 2, 200) + 2, # Phase II - faster
np.random.gamma(8, 1.5, 200) + 1, # Phase III - optimized
]
# Clip for visualization
relief_times = [np.clip(r, 0, 72) for r in relief_times]
# Colors
colors = ['#9CA3AF', '#F59E0B', '#8B5CF6', '#10B981']
# Create figure
fig, ax = plt.subplots(figsize=(11, 7), facecolor='white')
vp = ax.violinplot(relief_times, positions=range(len(treatments)), widths=0.7,
showmeans=False, showmedians=False, showextrema=False)
for i, body in enumerate(vp['bodies']):
body.set_facecolor(colors[i])
body.set_edgecolor('white')
body.set_linewidth(2)
body.set_alpha(0.75)
# Target time (clinical goal)
target_time = 12
ax.axhline(target_time, color='#10B981', linewidth=2, linestyle='--', alpha=0.7)
ax.fill_between([-0.5, 3.5], 0, target_time, color='#D1FAE5', alpha=0.3, zorder=0)
ax.text(3.55, target_time - 1, 'Target Zone', fontsize=9, color='#10B981',
fontweight='500', va='top')
# Add efficacy metrics
for i, times in enumerate(relief_times):
median = np.median(times)
pct_target = (times <= target_time).mean() * 100
# Median marker
ax.scatter(i, median, c='white', s=100, zorder=10,
edgecolor=colors[i], linewidth=2.5)
# Efficacy badge
badge_color = '#10B981' if pct_target > 50 else '#F59E0B' if pct_target > 25 else '#EF4444'
ax.annotate(f'{pct_target:.0f}%\neffective', xy=(i, 68),
ha='center', fontsize=9, fontweight='bold', color=badge_color,
bbox=dict(boxstyle='round,pad=0.4', facecolor='white',
edgecolor=badge_color, linewidth=1.5))
# Styling
ax.set_xticks(range(len(treatments)))
ax.set_xticklabels(treatments, fontsize=10, fontweight='500')
ax.set_ylabel('Time to Relief (hours)', fontsize=12, fontweight='500', color='#374151')
ax.set_ylim(0, 75)
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.3, color='#9CA3AF')
# Invert y-axis (lower is better)
ax.invert_yaxis()
plt.tight_layout()
plt.show()
Library
Matplotlib
Category
Statistical
More Violin Plot examples
☕