Violin Plot

Material Tensile Strength Analysis

Quality control testing with specification limits and pass rates

Output
Material Tensile Strength Analysis
Python
import matplotlib.pyplot as plt
import numpy as np

# Ultimate tensile strength (MPa)
np.random.seed(42)
materials = ['Steel\nA36', 'Aluminum\n6061', 'Titanium\nGr5', 'Carbon\nFiber', 'Inconel\n718']
# Simulated test results
strength_data = [
    np.random.normal(400, 25, 60),     # Steel
    np.random.normal(310, 20, 60),     # Aluminum
    np.random.normal(950, 40, 60),     # Titanium
    np.random.normal(600, 80, 60),     # Carbon Fiber (more variable)
    np.random.normal(1200, 50, 60),    # Inconel
]

# Material colors
colors = ['#6B7280', '#94A3B8', '#8B5CF6', '#1F2937', '#F59E0B']

# Create figure with industrial theme
fig, ax = plt.subplots(figsize=(12, 7), facecolor='#F9FAFB')
ax.set_facecolor('#F9FAFB')

vp = ax.violinplot(strength_data, positions=range(len(materials)), widths=0.75,
                   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.8)

# Specification limits for each material
spec_mins = [360, 275, 895, 500, 1100]
for i, spec in enumerate(spec_mins):
    ax.hlines(spec, i - 0.35, i + 0.35, color='#DC2626', linewidth=2, 
              linestyle='-', zorder=5)
    
    # Calculate pass rate
    pass_rate = (strength_data[i] >= spec).mean() * 100
    
    # Pass rate indicator
    indicator_color = '#10B981' if pass_rate > 95 else '#F59E0B' if pass_rate > 80 else '#EF4444'
    ax.scatter(i, spec - 30, c=indicator_color, s=200, marker='s', zorder=10, alpha=0.9)
    ax.text(i, spec - 30, f'{pass_rate:.0f}', ha='center', va='center',
            fontsize=9, fontweight='bold', color='white')

# Add percentile whiskers
for i, data in enumerate(strength_data):
    p5, median, p95 = np.percentile(data, [5, 50, 95])
    
    # Whisker
    ax.vlines(i, p5, p95, color=colors[i], linewidth=3, alpha=0.4)
    ax.scatter(i, median, c='white', s=80, zorder=10,
               edgecolor=colors[i], linewidth=2.5)

# Legend
ax.hlines([], 0, 0, color='#DC2626', linewidth=2, label='Spec Minimum')
ax.scatter([], [], c='#10B981', s=100, marker='s', label='Pass Rate')
ax.legend(loc='upper left', frameon=True, facecolor='white', 
          edgecolor='#E5E7EB', fontsize=10)

# Styling
ax.set_xticks(range(len(materials)))
ax.set_xticklabels(materials, fontsize=10, fontweight='600')
ax.set_ylabel('Ultimate Tensile Strength (MPa)', fontsize=12, fontweight='500', color='#374151')
ax.set_ylim(200, 1400)

ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.spines['left'].set_color('#D1D5DB')
ax.spines['bottom'].set_color('#D1D5DB')
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

Did this help you?

Support PyLucid to keep it free & growing

Support