Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Logscale plots with zero values in Matplotlib
Matplotlib's logarithmic scaling fails when data contains zero values because log(0) is undefined. The symlog (symmetric logarithm) scale solves this by using linear scaling near zero and logarithmic scaling for larger values.
Understanding Symlog Scale
The symlog scale combines linear and logarithmic scaling. It uses linear scaling within a threshold around zero and logarithmic scaling beyond that threshold, making it perfect for data containing zero values.
Basic Example with Zero Values
Here's how to create a symlog plot with data containing zeros ?
import matplotlib.pyplot as plt
# Data with zero values
x = [0, 1, 2, 0, 3, 10, 100]
y = [1, 0, 2, 3, 5, 50, 200]
plt.figure(figsize=(8, 6))
plt.plot(x, y, marker='o', linestyle='-', linewidth=2, markersize=8)
# Apply symlog scaling
plt.yscale('symlog')
plt.xscale('symlog')
plt.title('Symlog Plot with Zero Values')
plt.xlabel('X-axis (symlog scale)')
plt.ylabel('Y-axis (symlog scale)')
plt.grid(True, alpha=0.3)
plt.show()
Customizing the Linear Threshold
You can control where the linear-to-log transition occurs using the linthresh parameter ?
import matplotlib.pyplot as plt
import numpy as np
# Create data with wide range including zeros
x = np.array([0, 0.1, 1, 10, 100, 1000])
y = np.array([0, 0.5, 5, 0, 50, 500])
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
# Plot with default threshold
ax1.plot(x, y, 'bo-')
ax1.set_xscale('symlog')
ax1.set_yscale('symlog')
ax1.set_title('Default Threshold')
ax1.grid(True, alpha=0.3)
# Plot with custom threshold
ax2.plot(x, y, 'ro-')
ax2.set_xscale('symlog', linthresh=1)
ax2.set_yscale('symlog', linthresh=1)
ax2.set_title('Custom Threshold = 1')
ax2.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
Comparison of Scale Types
| Scale Type | Handles Zeros? | Best For |
|---|---|---|
linear |
Yes | Data with similar magnitudes |
log |
No | Positive data spanning multiple orders |
symlog |
Yes | Data with zeros and wide value ranges |
Practical Example: Scientific Data
Here's a realistic example showing how symlog scaling helps visualize scientific data with zero measurements ?
import matplotlib.pyplot as plt
import numpy as np
# Simulate experimental data with some zero readings
time = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
concentration = np.array([0, 0.01, 0.1, 0, 1, 10, 0, 100, 1000, 0, 5000])
plt.figure(figsize=(10, 6))
plt.plot(time, concentration, 'go-', linewidth=2, markersize=6, label='Concentration')
plt.yscale('symlog', linthresh=0.01)
plt.xlabel('Time (hours)')
plt.ylabel('Concentration (symlog scale)')
plt.title('Chemical Concentration Over Time\n(with zero readings)')
plt.legend()
plt.grid(True, alpha=0.3)
# Add annotations for zero values
zero_indices = np.where(concentration == 0)[0]
for idx in zero_indices:
plt.annotate('Zero', (time[idx], concentration[idx]),
xytext=(5, 5), textcoords='offset points', fontsize=8)
plt.show()
Conclusion
Use symlog scaling when your data contains zero values and spans multiple orders of magnitude. The linthresh parameter controls the linear region around zero, allowing fine-tuning of the visualization.
