Violin Plot
Crop Yield Comparison
Conventional vs regenerative farming yield distributions
Output
Python
import matplotlib.pyplot as plt
import numpy as np
# Crop yield data (tons per hectare)
np.random.seed(42)
crops = ['Wheat', 'Rice', 'Corn', 'Soybean', 'Cotton']
# Yield by farming method: conventional vs regenerative
conventional = [
np.random.normal(3.2, 0.6, 100),
np.random.normal(4.5, 0.8, 100),
np.random.normal(9.5, 1.5, 100),
np.random.normal(2.8, 0.5, 100),
np.random.normal(1.6, 0.3, 100),
]
regenerative = [
np.random.normal(3.5, 0.5, 100),
np.random.normal(4.8, 0.6, 100),
np.random.normal(10.2, 1.2, 100),
np.random.normal(3.1, 0.4, 100),
np.random.normal(1.8, 0.25, 100),
]
# Colors
color_conv = '#78716C'
color_regen = '#22C55E'
# Create figure with earth tones background
fig, ax = plt.subplots(figsize=(12, 7), facecolor='#FFFBEB')
ax.set_facecolor('#FFFBEB')
positions_conv = np.arange(len(crops)) - 0.2
positions_regen = np.arange(len(crops)) + 0.2
# Conventional violins
vp1 = ax.violinplot(conventional, positions=positions_conv, widths=0.35,
showmeans=False, showmedians=False, showextrema=False)
for body in vp1['bodies']:
body.set_facecolor(color_conv)
body.set_edgecolor('white')
body.set_linewidth(1.5)
body.set_alpha(0.7)
# Regenerative violins
vp2 = ax.violinplot(regenerative, positions=positions_regen, widths=0.35,
showmeans=False, showmedians=False, showextrema=False)
for body in vp2['bodies']:
body.set_facecolor(color_regen)
body.set_edgecolor('white')
body.set_linewidth(1.5)
body.set_alpha(0.7)
# Add yield improvement arrows
for i in range(len(crops)):
conv_med = np.median(conventional[i])
regen_med = np.median(regenerative[i])
improvement = ((regen_med - conv_med) / conv_med) * 100
# Medians
ax.scatter(positions_conv[i], conv_med, c='white', s=60, zorder=10,
edgecolor=color_conv, linewidth=2)
ax.scatter(positions_regen[i], regen_med, c='white', s=60, zorder=10,
edgecolor=color_regen, linewidth=2)
# Improvement annotation
y_pos = max(conv_med, regen_med) + 0.8
ax.annotate(f'+{improvement:.0f}%', xy=(i, y_pos),
ha='center', fontsize=10, fontweight='bold',
color='#15803D',
bbox=dict(boxstyle='round,pad=0.2', facecolor='#DCFCE7',
edgecolor='#22C55E', alpha=0.9))
# Legend
ax.scatter([], [], c=color_conv, s=100, label='Conventional', marker='s')
ax.scatter([], [], c=color_regen, s=100, label='Regenerative', marker='s')
ax.legend(loc='upper right', frameon=True, facecolor='white',
edgecolor='#E5E7EB', fontsize=11)
# Styling
ax.set_xticks(range(len(crops)))
ax.set_xticklabels(crops, fontsize=12, fontweight='600', color='#44403C')
ax.set_ylabel('Yield (tons/hectare)', fontsize=12, fontweight='500', color='#57534E')
ax.set_ylim(0, 14)
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.spines['left'].set_color('#D6D3D1')
ax.spines['bottom'].set_color('#D6D3D1')
ax.tick_params(colors='#78716C', labelsize=10)
ax.yaxis.grid(True, linestyle='--', alpha=0.4, color='#D6D3D1')
plt.tight_layout()
plt.show()
Library
Matplotlib
Category
Statistical
More Violin Plot examples
☕