Error Bars¶
Error bars display the uncertainty or variability of data points, essential for statistical and scientific visualizations.
Basic Error Bars¶
Symmetric Error Bars¶
import matplotlib.pyplot as plt
import numpy as np
x = np.array([1, 2, 3, 4, 5])
y = np.array([2, 4, 5, 4, 5])
yerr = np.array([0.5, 0.4, 0.6, 0.3, 0.5])
fig, ax = plt.subplots()
ax.errorbar(x, y, yerr=yerr, fmt='o', capsize=5)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_title('Basic Error Bars')
plt.show()
X and Y Error Bars¶
xerr = np.array([0.2, 0.3, 0.2, 0.25, 0.3])
yerr = np.array([0.5, 0.4, 0.6, 0.3, 0.5])
fig, ax = plt.subplots()
ax.errorbar(x, y, xerr=xerr, yerr=yerr, fmt='o', capsize=5)
plt.show()
Asymmetric Error Bars¶
For different upper and lower errors:
# Shape: (2, N) where [0] is lower, [1] is upper
yerr_asymmetric = np.array([
[0.3, 0.2, 0.4, 0.2, 0.3], # Lower errors
[0.5, 0.6, 0.4, 0.5, 0.7] # Upper errors
])
fig, ax = plt.subplots()
ax.errorbar(x, y, yerr=yerr_asymmetric, fmt='o', capsize=5)
ax.set_title('Asymmetric Error Bars')
plt.show()
Error Bar Styling¶
Format String¶
fig, ax = plt.subplots()
# Format: marker, line, color
ax.errorbar(x, y, yerr=yerr, fmt='s-b', capsize=5) # Square markers, solid line, blue
plt.show()
Detailed Styling¶
fig, ax = plt.subplots()
ax.errorbar(
x, y, yerr=yerr,
fmt='o', # Marker style
color='navy', # Point and line color
ecolor='lightblue', # Error bar color
elinewidth=2, # Error bar line width
capsize=6, # Cap size
capthick=2, # Cap thickness
markersize=8, # Marker size
markerfacecolor='white',
markeredgecolor='navy',
markeredgewidth=2,
label='Data'
)
ax.legend()
plt.show()
No Connecting Line¶
ax.errorbar(x, y, yerr=yerr, fmt='o', linestyle='none', capsize=5)
With Connecting Line¶
ax.errorbar(x, y, yerr=yerr, fmt='-o', capsize=5)
Key Parameters¶
| Parameter | Description | Default |
|---|---|---|
x, y |
Data coordinates | Required |
xerr |
X error values | None |
yerr |
Y error values | None |
fmt |
Format string | '' |
ecolor |
Error bar color | None (uses line color) |
elinewidth |
Error bar line width | None |
capsize |
Cap length in points | 0 |
capthick |
Cap line width | None |
uplims / lolims |
Upper/lower limits | False |
xlolims / xuplims |
X limits | False |
Upper and Lower Limits¶
Show one-sided limits when only bounds are known:
Upper Limits Only¶
fig, ax = plt.subplots()
y = np.array([2, 4, 5, 4, 5])
yerr = np.array([0.5, 0.4, 0.6, 0.3, 0.5])
uplims = np.array([True, False, True, False, True]) # Which points have upper limits
ax.errorbar(x, y, yerr=yerr, uplims=uplims, fmt='o', capsize=5)
ax.set_title('Upper Limits')
plt.show()
Lower Limits Only¶
lolims = np.array([False, True, False, True, False])
ax.errorbar(x, y, yerr=yerr, lolims=lolims, fmt='o', capsize=5)
Both Limits¶
ax.errorbar(x, y, yerr=yerr, uplims=uplims, lolims=lolims, fmt='o', capsize=5)
Practical Examples¶
1. Experimental Data¶
import matplotlib.pyplot as plt
import numpy as np
# Simulated experimental data with measurement uncertainty
temperature = np.array([20, 40, 60, 80, 100])
pressure = np.array([1.0, 1.8, 2.5, 3.1, 3.8])
pressure_err = np.array([0.1, 0.15, 0.12, 0.18, 0.2])
fig, ax = plt.subplots()
ax.errorbar(temperature, pressure, yerr=pressure_err,
fmt='o', capsize=5, capthick=1.5,
color='darkblue', ecolor='lightblue',
label='Measurements')
# Add fit line
coeffs = np.polyfit(temperature, pressure, 1)
fit_line = np.poly1d(coeffs)
ax.plot(temperature, fit_line(temperature), 'r--', label='Linear Fit')
ax.set_xlabel('Temperature (°C)')
ax.set_ylabel('Pressure (atm)')
ax.set_title('Pressure vs Temperature')
ax.legend()
plt.show()
2. Comparing Groups with Error Bars¶
import matplotlib.pyplot as plt
import numpy as np
categories = ['A', 'B', 'C', 'D']
x = np.arange(len(categories))
width = 0.35
# Group 1
means1 = [20, 35, 30, 35]
std1 = [2, 3, 4, 2]
# Group 2
means2 = [25, 32, 34, 20]
std2 = [3, 4, 2, 3]
fig, ax = plt.subplots()
ax.bar(x - width/2, means1, width, yerr=std1, label='Group 1', capsize=5)
ax.bar(x + width/2, means2, width, yerr=std2, label='Group 2', capsize=5)
ax.set_ylabel('Values')
ax.set_xticks(x)
ax.set_xticklabels(categories)
ax.legend()
plt.show()
3. Time Series with Confidence Intervals¶
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(42)
dates = np.arange(0, 10, 0.5)
values = np.sin(dates) + np.random.normal(0, 0.1, len(dates))
errors = np.random.uniform(0.1, 0.3, len(dates))
fig, ax = plt.subplots(figsize=(10, 5))
# Error bars
ax.errorbar(dates, values, yerr=errors, fmt='o-', capsize=3,
color='steelblue', ecolor='lightsteelblue',
alpha=0.8)
# Shaded confidence region alternative
ax.fill_between(dates, values - errors, values + errors,
alpha=0.2, color='steelblue')
ax.set_xlabel('Time')
ax.set_ylabel('Value')
ax.set_title('Time Series with Uncertainty')
plt.show()
4. Multiple Series¶
import matplotlib.pyplot as plt
import numpy as np
x = np.array([1, 2, 3, 4, 5])
fig, ax = plt.subplots()
# Series 1
y1 = np.array([2.1, 3.5, 4.2, 5.1, 6.3])
err1 = np.array([0.3, 0.2, 0.4, 0.3, 0.2])
ax.errorbar(x, y1, yerr=err1, fmt='o-', capsize=4, label='Method A')
# Series 2
y2 = np.array([1.8, 3.2, 4.5, 4.8, 5.9])
err2 = np.array([0.2, 0.3, 0.2, 0.4, 0.3])
ax.errorbar(x, y2, yerr=err2, fmt='s--', capsize=4, label='Method B')
# Series 3
y3 = np.array([2.5, 3.8, 4.0, 5.3, 6.0])
err3 = np.array([0.4, 0.2, 0.3, 0.2, 0.4])
ax.errorbar(x, y3, yerr=err3, fmt='^:', capsize=4, label='Method C')
ax.legend()
ax.set_xlabel('Sample')
ax.set_ylabel('Measurement')
plt.show()
5. Logarithmic Scale with Error Bars¶
import matplotlib.pyplot as plt
import numpy as np
x = np.array([1, 2, 5, 10, 20, 50, 100])
y = np.array([0.5, 1.2, 3.5, 8.0, 22, 60, 150])
yerr = y * 0.15 # 15% relative error
fig, ax = plt.subplots()
ax.errorbar(x, y, yerr=yerr, fmt='o', capsize=4)
ax.set_xscale('log')
ax.set_yscale('log')
ax.set_xlabel('X (log scale)')
ax.set_ylabel('Y (log scale)')
ax.set_title('Log-Log Plot with Error Bars')
plt.show()
6. Horizontal Error Bars¶
import matplotlib.pyplot as plt
import numpy as np
y = np.array([1, 2, 3, 4, 5])
x = np.array([10, 25, 40, 35, 50])
xerr = np.array([3, 5, 4, 6, 4])
fig, ax = plt.subplots()
ax.errorbar(x, y, xerr=xerr, fmt='o', capsize=5,
color='green', ecolor='lightgreen')
ax.set_xlabel('X Value')
ax.set_ylabel('Category')
ax.set_title('Horizontal Error Bars')
plt.show()
Combining with Other Plot Types¶
Error Bars on Scatter Plot¶
fig, ax = plt.subplots()
# Scatter with color mapping
colors = np.random.rand(len(x))
scatter = ax.scatter(x, y, c=colors, s=100, cmap='viridis', zorder=2)
ax.errorbar(x, y, yerr=yerr, fmt='none', ecolor='gray', capsize=3, zorder=1)
plt.colorbar(scatter)
plt.show()
Error Bars on Bar Chart¶
fig, ax = plt.subplots()
categories = ['A', 'B', 'C', 'D']
values = [23, 45, 56, 78]
errors = [3, 5, 4, 6]
bars = ax.bar(categories, values, yerr=errors, capsize=5,
color='steelblue', edgecolor='black')
plt.show()
Common Pitfalls¶
1. Error Values Must Be Positive¶
# WRONG: Negative error values
yerr = np.array([-0.5, 0.4, 0.6])
# CORRECT: Use absolute values
yerr = np.abs(np.array([-0.5, 0.4, 0.6]))
2. Asymmetric Error Shape¶
# WRONG: Shape (N, 2)
yerr = np.array([[0.3, 0.5], [0.2, 0.6], [0.4, 0.4]])
# CORRECT: Shape (2, N)
yerr = np.array([
[0.3, 0.2, 0.4], # Lower errors
[0.5, 0.6, 0.4] # Upper errors
])
3. Caps Not Showing¶
# Caps have size 0 by default
ax.errorbar(x, y, yerr=yerr) # No visible caps
# Set capsize to show caps
ax.errorbar(x, y, yerr=yerr, capsize=5)