# 3. Comprehensive visualization
fig, axes = plt.subplots(2, 2, figsize=(12, 8))
# Histogram
axes[0, 0].hist(data, bins=30, edgecolor='black', alpha=0.7, color='steelblue')
axes[0, 0].axvline(np.mean(data), color='red', linestyle='--', label='Mean')
axes[0, 0].axvline(np.median(data), color='green', linestyle='--', label='Median')
axes[0, 0].set_title('Histogram', fontsize=12)
axes[0, 0].set_xlabel('Value')
axes[0, 0].set_ylabel('Frequency')
axes[0, 0].legend()
# Boxplot
axes[0, 1].boxplot(data, vert=True)
axes[0, 1].set_title('Boxplot', fontsize=12)
axes[0, 1].set_ylabel('Value')
axes[0, 1].grid(alpha=0.3, axis='y')
# Q-Q Plot
standardized = (data - np.mean(data)) / np.std(data, ddof=1)
standardized = np.sort(standardized)
n = len(standardized)
theoretical = np.array([np.percentile(np.random.standard_normal(10000),
100 * (i - 0.5) / n) for i in range(1, n + 1)])
axes[1, 0].scatter(theoretical, standardized, alpha=0.4, s=20)
axes[1, 0].plot([-3, 3], [-3, 3], 'r--', linewidth=2)
axes[1, 0].set_xlabel('Theoretical Quantiles')
axes[1, 0].set_ylabel('Sample Quantiles')
axes[1, 0].set_title('Q-Q Plot', fontsize=12)
axes[1, 0].grid(alpha=0.3)
# Bootstrap distribution
axes[1, 1].hist(boot_means, bins=30, edgecolor='black', alpha=0.7, color='lightgreen')
axes[1, 1].axvline(ci[0], color='r', linestyle='--', linewidth=2, label='95% CI')
axes[1, 1].axvline(ci[1], color='r', linestyle='--', linewidth=2)
axes[1, 1].set_title('Bootstrap Distribution', fontsize=12)
axes[1, 1].set_xlabel('Bootstrap Mean')
axes[1, 1].legend()
plt.tight_layout()
plt.show()