Skip to content

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)