a better default colormap for matplotlib scipy 2015 nathaniel smith and stC383C2A9fan van der walt xAoljeRJ3lU
The Viridis Revolution: Why and How to Adopt Modern Colormaps in Matplotlib and SciPy
Nathaniel Smith and Stefan van der Walt proposed a fundamental shift in scientific visualization in 2015, arguing that the default rainbow colormaps (like hsv and jet) used in Matplotlib were perceptually misleading. Their influential work led to the adoption of viridis and other perceptually uniform colormaps as the new standard in scientific computing. This article explains why this change matters and how to implement it effectively in your workflow.
Key Takeaways
- Perceptual Uniformity: Rainbow colormaps (e.g.,
jet) create artificial data banding and hide subtle variations, whileviridisensures equal changes in data value are perceived as equal changes in color intensity. - Accessibility:
viridisis colorblind-safe and prints well in grayscale, making it superior for journal publications and diverse audiences. - Implementation: Since Matplotlib v1.5+ (2015),
viridisis the default. For older versions or explicit control, setplt.cm.viridisor update yourrcParams. - SciPy Integration: SciPy’s image processing and plotting modules benefit directly from these updates, ensuring consistent visual standards across the scientific Python ecosystem.
The Core Problem: Why "Rainbow" Colormaps Are Misleading
In 2015, Nathaniel Smith and Stefan van der Walt published a widely cited critique of standard scientific plotting defaults. They demonstrated that hue-based colormaps like hsv (rainbow) violate the principle of luminance uniformity. When a colormap’s color changes too quickly in hue relative to lightness, the human eye perceives distinct "bands" or false edges that do not exist in the data. This is known as the "rainbow artifact."
For researchers, this is not just an aesthetic issue; it is a data integrity issue. Misleading visualizations can lead to incorrect interpretations of peaks, valleys, and noise in complex datasets.
What Makes a Colormap "Better"?
A superior scientific colormap must meet three criteria:
- Perceptual Uniformity: The lightness of the color should change monotonically and linearly with the data value. This ensures that the eye can accurately distinguish small differences in data magnitude.
- Colorblind Safety: The most common form of color vision deficiency (deuteranopia/protanopia) must not cause two different data values to appear as the same color.
- Grayscale Robustness: The map must remain interpretable when printed in black and white, which is still common in many academic journals.
The viridis colormap, designed by Stéfan van der Walt and Nathaniel Smith (with contributions from others at the SciPy conference), was specifically optimized to meet these criteria. It transitions from purple to yellow, providing a continuous luminance gradient.
Comparison: Legacy vs. Modern Colormaps
The table below compares the legacy defaults with the recommended modern alternatives.
| Colormap | Type | Perceptual Uniformity | Colorblind Safe | Grayscale Printable | Recommendation |
|---|---|---|---|---|---|
jet / rainbow |
Hue-based | Poor (creates banding) | No | Yes | Avoid |
hsv |
Hue-based | Poor | No | Yes | Avoid |
viridis |
Perceptually Uniform | Excellent | Yes | Yes | Recommended Default |
plasma |
Perceptually Uniform | Excellent | Yes | Yes | Recommended Alternative |
cividis |
Colorblind Optimized | Good | Excellent | Yes | Best for CVD Users |
Implementation Checklist
Ensure your workflow adheres to best practices with this checklist:
- Update Matplotlib: Ensure you are using Matplotlib ≥ 1.5, where
viridisis the default. - Explicitly Set Colormaps: Do not rely on defaults in shared code. Use
cmap='viridis'inplt.imshow()orplt.contourf()for clarity. - Use Diverging Maps for Diverging Data: If your data has a meaningful zero point (e.g., temperature anomaly), use
RdBuorcoolwarminstead of sequential maps likeviridis. - Verify Grayscale Output: Always save a test PNG and convert it to grayscale to check if the data structure remains visible.
Frequently Asked Questions (FAQ)
1. Why was jet so popular if it is so flawed?
jet was popular primarily due to legacy systems (MATLAB) and the human desire for vibrant, "colorful" plots. It provides high saturation at the extremes (red/blue), which makes plots look visually striking to those unfamiliar with data visualization theory. However, its non-linear luminance creates "halos" around bright spots, distorting the viewer's perception of the data's topography. Modern colormaps like viridis prioritize accuracy over vibrancy.
2. Does SciPy have its own colormap engine, or does it rely on Matplotlib?
SciPy relies on Matplotlib for its visualization capabilities. SciPy does not generate standalone image files; it processes data, which is then rendered by Matplotlib. Therefore, when Nathaniel Smith and Stefan van der Walt advocated for better defaults, the changes were implemented in Matplotlib. However, any code using scipy.misc or scipy.ndimage that feeds data into Matplotlib plots will automatically benefit from these improved defaults.
3. How do I make viridis the default permanently in my project?
You can set it globally in your script or notebook using Matplotlib's rcParams. Add the following at the top of your Python file:
import matplotlib.pyplot as plt
plt.rcParams['image.cmap'] = 'viridis'
This ensures that every subsequent plot that uses a colormap without explicitly specifying one will use viridis, safeguarding against accidental use of legacy maps.