Matplotlib 色彩映射(Colormap):Python 颜色映射完整指南
Updated on
为数据可视化选择合适的颜色,难度常常被低估。选了彩虹色 colormap,你的 heatmap 看起来很“震撼”——但由于人眼感知并不均匀,它会扭曲数据、误导读者,并且对色觉缺陷人群几乎完全不可用。用单一色相的调色板,又可能让细微模式消失在一片几乎相同的色块里。图表是“揭示洞见”还是“掩盖信息”,往往就取决于一个决定:colormap。
Matplotlib 自带 150+ 的内置 colormap,并提供灵活的 API 来构建你自己的 colormap。问题不在于选项不够——而在于你是否知道该用哪一种、何时使用、以及如何针对特定数据集进行定制。糟糕的选择会在不知不觉中破坏可视化的准确性;正确的选择则能让复杂数据立刻变得可读。
本指南覆盖 Matplotlib colormap 的所有实用要点:四大类别、最重要的内置 colormap、如何在不同图形类型中应用、如何从零构建自定义 colormap,以及如何选择既科学准确又具可访问性的配色方案。
Matplotlib 中的 Colormap 是什么?
colormap 是一种映射函数,用于把标量数据值转换为颜色。给定一个数值(通常会被归一化到 0--1 范围),colormap 会返回一个 RGBA 颜色元组。Matplotlib 将 colormap 表示为继承自 matplotlib.colors.Colormap 的对象,所有接受 cmap 参数的绘图函数,底层都使用这套机制。
import matplotlib.pyplot as plt
import numpy as np
# A colormap is a callable: pass a float in [0, 1], get an RGBA tuple
cmap = plt.colormaps['viridis']
print(cmap(0.0)) # dark purple
print(cmap(0.5)) # teal-green
print(cmap(1.0)) # bright yellow当你写下 plt.imshow(data, cmap='viridis') 时,Matplotlib 会先使用 Normalize 对象把你的数据归一化到 [0, 1],然后把每个归一化后的数值送入 colormap 来得到最终的像素颜色。理解这个“两步过程”——先归一化,再查色——是你精确控制图中颜色表现的关键。
Colormap 的四大类别
Matplotlib 将 colormap 按功能划分为四类。每类适合不同的数据类型;用错类别是最常见、也最致命的 colormap 错误。
顺序型(Sequential)Colormaps
顺序型 colormap 会在单一色相或较窄的色相范围内,从浅到深(或从深到浅)平滑变化。它们用于具有自然“从低到高”顺序、且没有特殊中点的数据。
适用场景: 温度读数、人口密度、海拔高度、概率、任何具有明确方向的连续变量。
典型示例: viridis, plasma, inferno, magma, cividis, Blues, Greens, OrRd, YlGnBu
import matplotlib.pyplot as plt
import numpy as np
data = np.random.rand(12, 12)
fig, axes = plt.subplots(1, 3, figsize=(14, 4))
for ax, name in zip(axes, ['viridis', 'plasma', 'inferno']):
im = ax.imshow(data, cmap=name)
ax.set_title(f'Sequential: {name}')
fig.colorbar(im, ax=ax, shrink=0.8)
plt.tight_layout()
plt.show()发散型(Diverging)Colormaps
发散型 colormap 使用两种对比色相,并在中点处汇合为中性色(通常是白色或浅灰)。它们强调数据相对于中心值向两侧的偏离。
适用场景: 温度异常(高于/低于平均值)、相关矩阵、盈亏、任何“0 或某个中点”具有特殊意义的数据。
典型示例: coolwarm, RdBu, RdYlGn, BrBG, PiYG, seismic, bwr
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(42)
data = np.random.randn(10, 10) # Values centered around zero
fig, axes = plt.subplots(1, 3, figsize=(14, 4))
for ax, name in zip(axes, ['coolwarm', 'RdBu', 'seismic']):
im = ax.imshow(data, cmap=name, vmin=-3, vmax=3)
ax.set_title(f'Diverging: {name}')
fig.colorbar(im, ax=ax, shrink=0.8)
plt.tight_layout()
plt.show()提示: 请始终围绕中点对称地设置 vmin 和 vmax,这样中性色才会对齐到 0(或你选择的中心值)。
定性(Qualitative)Colormaps
定性 colormap 提供一组彼此视觉上明显区分的颜色,但不暗示任何顺序关系。每种颜色都尽可能与相邻颜色差异最大,因此非常适合分类标签。
适用场景: 聚类标签、分类散点图、无序分组的柱状图。
典型示例: tab10, tab20, Set1, Set2, Set3, Paired, Accent
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(7)
categories = 6
x = np.concatenate([np.random.randn(30) + i * 3 for i in range(categories)])
y = np.concatenate([np.random.randn(30) + i * 1.5 for i in range(categories)])
labels = np.concatenate([np.full(30, i) for i in range(categories)])
plt.figure(figsize=(9, 6))
scatter = plt.scatter(x, y, c=labels, cmap='tab10', s=50, alpha=0.8, edgecolors='white')
plt.colorbar(scatter, label='Category')
plt.title('Qualitative Colormap: tab10')
plt.xlabel('X')
plt.ylabel('Y')
plt.show()循环型(Cyclic)Colormaps
循环型 colormap 的起点与终点颜色相同,适合“会回绕”的数据——例如角度、相位、一天中的时间、风向。
适用场景: 相位数据、罗盘方向、周期信号、一天中的小时。
典型示例: twilight, twilight_shifted, hsv
import matplotlib.pyplot as plt
import numpy as np
theta = np.linspace(0, 2 * np.pi, 300)
r = np.linspace(0, 1, 300)
T, R = np.meshgrid(theta, r)
Z = T # Color represents angle
fig, ax = plt.subplots(subplot_kw={'projection': 'polar'}, figsize=(6, 6))
im = ax.pcolormesh(T, R, Z, cmap='twilight', shading='auto')
fig.colorbar(im, ax=ax, label='Angle (radians)')
ax.set_title('Cyclic Colormap: twilight')
plt.show()对比表:Colormap 类别
| Category | Purpose | Midpoint Matters? | Ordering? | Best For | Examples |
|---|---|---|---|---|---|
| Sequential | 从低到高的数值 | 否 | 是 | 密度、温度、计数 | viridis, plasma, inferno, Blues |
| Diverging | 相对中心的偏离 | 是 | 是(两侧) | 异常、相关性、盈亏 | coolwarm, RdBu, BrBG |
| Qualitative | 区分类别 | 否 | 否 | 标签、聚类、分组 | tab10, Set1, Paired |
| Cyclic | 回绕数据 | 否 | 环形 | 相位、角度、一天时间 | twilight, hsv |
内置 Colormaps 速查
Matplotlib 包含多个家族的 colormap。下面按类别给出最常用的集合。
感知均匀的顺序型(Perceptually Uniform Sequential)
这些 colormap 被设计为:数据的等步长变化能对应人眼感知亮度的等步长变化。对大多数场景,它们是默认首选。
| Colormap | Description | Colorblind Safe |
|---|---|---|
viridis | 紫到黄,Matplotlib 2.0 起默认 | Yes |
plasma | 紫到黄,对比度更高 | Yes |
inferno | 黑到黄,途经红色 | Yes |
magma | 黑到白,途经紫与粉 | Yes |
cividis | 蓝到黄,专为色觉缺陷优化 | Yes |
常见发散型(Diverging)Colormaps
| Colormap | Description | Colorblind Safe |
|---|---|---|
coolwarm | 蓝到红,过渡平滑 | Partially |
RdBu | 红到蓝,对比强 | No |
RdYlGn | 红-黄-绿 | No |
BrBG | 棕到青绿 | Partially |
PiYG | 粉到绿 | Partially |
seismic | 蓝到红,饱和度强 | No |
在不同图类型中使用 Colormaps
使用 imshow 绘制 Heatmap
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(42)
data = np.random.rand(8, 10)
fig, ax = plt.subplots(figsize=(10, 6))
im = ax.imshow(data, cmap='YlOrRd', aspect='auto')
ax.set_xlabel('Columns')
ax.set_ylabel('Rows')
ax.set_title('Heatmap with YlOrRd Colormap')
fig.colorbar(im, ax=ax, label='Value')
plt.tight_layout()
plt.show()颜色编码的散点图(Scatter)
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(42)
n = 300
x = np.random.randn(n)
y = np.random.randn(n)
distance = np.sqrt(x**2 + y**2)
plt.figure(figsize=(8, 6))
sc = plt.scatter(x, y, c=distance, cmap='magma', s=40, alpha=0.8, edgecolors='gray', linewidths=0.3)
plt.colorbar(sc, label='Distance from Origin')
plt.xlabel('X')
plt.ylabel('Y')
plt.title('Scatter Plot with magma Colormap')
plt.show()等高线图(Contour)
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(-3, 3, 200)
y = np.linspace(-3, 3, 200)
X, Y = np.meshgrid(x, y)
Z = np.sin(X) * np.cos(Y)
fig, axes = plt.subplots(1, 2, figsize=(13, 5))
# Filled contour
cf = axes[0].contourf(X, Y, Z, levels=20, cmap='RdBu')
fig.colorbar(cf, ax=axes[0])
axes[0].set_title('contourf with RdBu')
# Line contour with colormap
cl = axes[1].contour(X, Y, Z, levels=15, cmap='plasma')
axes[1].clabel(cl, inline=True, fontsize=8)
axes[1].set_title('contour with plasma')
plt.tight_layout()
plt.show()用于非规则网格的 pcolormesh
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(0)
x = np.linspace(0, 4, 50)
y = np.linspace(0, 3, 40)
X, Y = np.meshgrid(x, y)
Z = np.exp(-(X - 2)**2 - (Y - 1.5)**2) + 0.5 * np.sin(3 * X) * np.cos(3 * Y)
plt.figure(figsize=(9, 6))
pcm = plt.pcolormesh(X, Y, Z, cmap='cividis', shading='auto')
plt.colorbar(pcm, label='Intensity')
plt.xlabel('X')
plt.ylabel('Y')
plt.title('pcolormesh with cividis Colormap')
plt.tight_layout()
plt.show()Colorbar 自定义
colorbar 是 colormap 的“图例”。正确地自定义它对可读性至关重要。
基础 colorbar 选项
import matplotlib.pyplot as plt
import numpy as np
data = np.random.rand(10, 10)
fig, ax = plt.subplots(figsize=(8, 6))
im = ax.imshow(data, cmap='viridis')
cbar = fig.colorbar(im, ax=ax, orientation='vertical', shrink=0.8, pad=0.02)
cbar.set_label('Measurement Value', fontsize=12)
cbar.ax.tick_params(labelsize=10)
plt.title('Colorbar Customization')
plt.tight_layout()
plt.show()使用 BoundaryNorm 的离散 colorbar
当你的数据天然落在离散区间(风险等级、评分档位)时,使用 BoundaryNorm 来创建清晰的颜色边界,而不是平滑渐变。
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import numpy as np
data = np.random.rand(10, 10) * 100
bounds = [0, 20, 40, 60, 80, 100]
norm = mcolors.BoundaryNorm(bounds, ncolors=256)
fig, ax = plt.subplots(figsize=(8, 6))
im = ax.imshow(data, cmap='RdYlGn', norm=norm)
cbar = fig.colorbar(im, ax=ax, ticks=bounds)
cbar.set_label('Score')
ax.set_title('Discrete Colorbar with BoundaryNorm')
plt.tight_layout()
plt.show()水平 colorbar
import matplotlib.pyplot as plt
import numpy as np
data = np.random.rand(8, 12)
fig, ax = plt.subplots(figsize=(10, 5))
im = ax.imshow(data, cmap='plasma')
cbar = fig.colorbar(im, ax=ax, orientation='horizontal', fraction=0.046, pad=0.12)
cbar.set_label('Value')
ax.set_title('Horizontal Colorbar')
plt.tight_layout()
plt.show()创建自定义 Colormaps
当内置 colormap 无法满足需求——例如企业品牌色、领域惯例、或特定的感知要求——Matplotlib 提供了两类构建方式。
ListedColormap:由颜色列表构建
ListedColormap 用明确的颜色列表创建 colormap。每种颜色在 [0, 1] 区间占据等宽比例。
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import numpy as np
# Define colors by name, hex, or RGB tuple
colors = ['#2c3e50', '#2980b9', '#27ae60', '#f39c12', '#e74c3c']
cmap_custom = mcolors.ListedColormap(colors)
data = np.random.rand(10, 10)
fig, ax = plt.subplots(figsize=(8, 6))
im = ax.imshow(data, cmap=cmap_custom)
fig.colorbar(im, ax=ax)
ax.set_title('Custom ListedColormap (5 colors)')
plt.tight_layout()
plt.show()LinearSegmentedColormap:平滑渐变
LinearSegmentedColormap 用于创建平滑的颜色过渡。最简单的方法是 from_list,它会在锚点颜色之间进行线性插值。
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import numpy as np
# Smooth gradient from dark blue through white to dark red
colors = ['#1a1a6e', '#4a90d9', '#ffffff', '#d94a4a', '#6e1a1a']
cmap_diverge = mcolors.LinearSegmentedColormap.from_list('custom_diverge', colors)
np.random.seed(42)
data = np.random.randn(12, 12)
fig, ax = plt.subplots(figsize=(8, 6))
im = ax.imshow(data, cmap=cmap_diverge, vmin=-3, vmax=3)
fig.colorbar(im, ax=ax, label='Standard Deviations')
ax.set_title('Custom Diverging Colormap')
plt.tight_layout()
plt.show()进阶:分段字典(Segment Dictionary)格式
如果你需要对每个颜色通道的过渡进行完全控制,可以定义分段字典。每个通道(red/green/blue)都由 (x, y_left, y_right) 元组列表组成,用来指定锚点。
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import numpy as np
# Custom colormap: black -> blue -> cyan -> yellow -> white
cdict = {
'red': [(0.0, 0.0, 0.0), (0.25, 0.0, 0.0), (0.5, 0.0, 0.0),
(0.75, 1.0, 1.0), (1.0, 1.0, 1.0)],
'green': [(0.0, 0.0, 0.0), (0.25, 0.0, 0.0), (0.5, 1.0, 1.0),
(0.75, 1.0, 1.0), (1.0, 1.0, 1.0)],
'blue': [(0.0, 0.0, 0.0), (0.25, 1.0, 1.0), (0.5, 1.0, 1.0),
(0.75, 0.0, 0.0), (1.0, 1.0, 1.0)]
}
cmap_seg = mcolors.LinearSegmentedColormap('custom_seg', cdict)
data = np.random.rand(10, 10)
fig, ax = plt.subplots(figsize=(8, 6))
im = ax.imshow(data, cmap=cmap_seg)
fig.colorbar(im, ax=ax)
ax.set_title('Segment Dictionary Colormap')
plt.tight_layout()
plt.show()注册自定义 Colormap
注册 colormap 后,你就能像使用内置 colormap 一样通过名字引用它:
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
colors = ['#0d0887', '#7e03a8', '#cc4778', '#f89540', '#f0f921']
my_cmap = mcolors.LinearSegmentedColormap.from_list('my_palette', colors)
plt.colormaps.register(cmap=my_cmap)
# Now use it by name anywhere
# plt.imshow(data, cmap='my_palette')反转 Colormap
在任意 colormap 名称后追加 _r 即可得到反转版本。当你希望视觉强调方向相反时很有用——例如让更高的数值更暗而不是更亮。
import matplotlib.pyplot as plt
import numpy as np
data = np.random.rand(8, 8)
fig, axes = plt.subplots(1, 2, figsize=(12, 5))
axes[0].imshow(data, cmap='viridis')
axes[0].set_title('viridis (default)')
axes[1].imshow(data, cmap='viridis_r')
axes[1].set_title('viridis_r (reversed)')
plt.tight_layout()
plt.show()每个内置 colormap 都有对应的反转版本:plasma_r, coolwarm_r, RdBu_r, inferno_r 等。
截取并提取 Colormap 子区间
有时你只需要 colormap 的一部分。可以结合 Colormap.__call__、np.linspace 与 ListedColormap 提取切片:
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import numpy as np
# Extract the middle 50% of the viridis colormap
full_cmap = plt.colormaps['viridis']
colors = full_cmap(np.linspace(0.25, 0.75, 256))
truncated_cmap = mcolors.ListedColormap(colors)
data = np.random.rand(10, 10)
fig, axes = plt.subplots(1, 2, figsize=(12, 5))
axes[0].imshow(data, cmap='viridis')
axes[0].set_title('Full viridis')
axes[1].imshow(data, cmap=truncated_cmap)
axes[1].set_title('Truncated viridis (25%-75%)')
plt.tight_layout()
plt.show()归一化(Normalization):控制数据如何映射到颜色
归一化决定了原始数据值如何在查色之前转换到 [0, 1]。默认是线性归一化,但 Matplotlib 提供了多种替代方案。
| Normalization | Class | When to Use |
|---|---|---|
| Linear | Normalize | 默认,数据分布较均匀 |
| Logarithmic | LogNorm | 数据跨越多个数量级 |
| Symmetric log | SymLogNorm | 数据有正负号,且需要近似对数缩放 |
| Power | PowerNorm | 自定义非线性压缩 |
| Two-slope | TwoSlopeNorm | 发散数据且两侧范围不对称 |
| Boundary | BoundaryNorm | 离散分箱边界 |
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import numpy as np
np.random.seed(42)
data = np.random.lognormal(mean=2, sigma=1.5, size=(20, 20))
fig, axes = plt.subplots(1, 3, figsize=(16, 5))
# Linear (default)
im0 = axes[0].imshow(data, cmap='magma')
fig.colorbar(im0, ax=axes[0])
axes[0].set_title('Linear Normalize')
# LogNorm
im1 = axes[1].imshow(data, cmap='magma', norm=mcolors.LogNorm())
fig.colorbar(im1, ax=axes[1])
axes[1].set_title('LogNorm')
# PowerNorm (gamma=0.5 = square root)
im2 = axes[2].imshow(data, cmap='magma', norm=mcolors.PowerNorm(gamma=0.5))
fig.colorbar(im2, ax=axes[2])
axes[2].set_title('PowerNorm (gamma=0.5)')
plt.tight_layout()
plt.show()为你的数据选择合适的 Colormap
选择 colormap 是一种会产生真实后果的设计决策。下面是一套实用的决策框架:
-
数据是顺序型(低到高)吗? 使用顺序型 colormap。先从
viridis开始;需要更强对比可试plasma或inferno。 -
数据是围绕有意义中心发散的吗? 使用发散型 colormap。想要更柔和选
coolwarm,对比更强选RdBu。并对称设置vmin与vmax。 -
数据是无序的类别型吗? 使用定性 colormap。最多 10 类用
tab10,最多 20 类用tab20。 -
数据会回绕(角度、相位)吗? 使用循环型 colormap。
twilight是现代最佳选择。 -
受众包含色觉缺陷用户吗? 顺序型用
cividis或viridis。避免RdYlGn这类红绿组合。 -
图会以灰度打印吗? 使用
viridis,plasma,inferno,magma——它们保持亮度单调变化。
可访问性:色盲友好的 Colormaps
大约 8% 的男性与 0.5% 的女性存在某种色觉缺陷,最常见的是难以区分红与绿。感知均匀的 colormap(viridis, plasma, inferno, magma, cividis)专门设计为在最常见色盲类型下仍保持可读性。
为了可访问性应避免的 colormap: jet, rainbow, RdYlGn, RdYlBu(当红绿区分很关键时)、hot。
为什么 jet 有害: jet colormap(从蓝经青、绿、黄到红的彩虹)在感知上不均匀,会在数据中制造“虚假的边界”。实际差异很大的区域可能看起来相似,而青绿附近的小差异却会显得非常剧烈。它对 deuteranopia(红绿色盲)用户也几乎完全失效。
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(42)
data = np.random.rand(15, 15)
fig, axes = plt.subplots(1, 2, figsize=(12, 5))
axes[0].imshow(data, cmap='jet')
axes[0].set_title('jet (avoid for scientific use)')
axes[1].imshow(data, cmap='cividis')
axes[1].set_title('cividis (colorblind-safe)')
plt.tight_layout()
plt.show()列出所有可用的 Colormaps
查看你当前 Matplotlib 版本中所有可用的 colormap:
import matplotlib.pyplot as plt
# All colormap names, sorted
all_cmaps = sorted(plt.colormaps())
print(f"Total colormaps: {len(all_cmaps)}")
# Filter out reversed versions
base_cmaps = [c for c in all_cmaps if not c.endswith('_r')]
print(f"Base colormaps (excluding _r): {len(base_cmaps)}")将它们可视化展示:
import matplotlib.pyplot as plt
import numpy as np
gradient = np.linspace(0, 1, 256).reshape(1, -1)
cmaps_to_show = ['viridis', 'plasma', 'inferno', 'magma', 'cividis',
'coolwarm', 'RdBu', 'seismic',
'tab10', 'Set1',
'twilight']
fig, axes = plt.subplots(len(cmaps_to_show), 1, figsize=(10, len(cmaps_to_show) * 0.5))
fig.subplots_adjust(hspace=0.4)
for ax, name in zip(axes, cmaps_to_show):
ax.imshow(gradient, aspect='auto', cmap=name)
ax.set_ylabel(name, rotation=0, labelpad=80, fontsize=10, va='center')
ax.set_xticks([])
ax.set_yticks([])
fig.suptitle('Matplotlib Colormap Samples', fontsize=14, y=1.01)
plt.tight_layout()
plt.show()使用 PyGWalker 进行交互式可视化
在交互式探索数据集时,为每张图手动配置 colormap 可能会拖慢节奏。PyGWalker (opens in a new tab) 是一个开源 Python 库,可以把任意 pandas 或 polars DataFrame 直接变成 Jupyter 内的 Tableau 风格交互界面。你可以将变量拖到坐标轴上、指定颜色编码、切换可视化类型——无需手写 colormap 或绘图代码。
import pandas as pd
import pygwalker as pyg
# Load your data
df = pd.read_csv('your_data.csv')
# Launch the interactive UI -- color encoding, binning, and filtering are all point-and-click
walker = pyg.walk(df)这在探索性分析阶段尤其有用:你可能还在决定该可视化哪些变量、用什么颜色编码最清晰。一旦找到合适的图形,你随时可以在 Matplotlib 中用精确的 colormap 配置进行复现。
常见陷阱与规避方法
| Pitfall | Problem | Solution |
|---|---|---|
默认使用 jet | 感知不均匀、不可访问 | 换成 viridis 或其他感知均匀 colormap |
| 用发散型映射来表示顺序数据 | 暗示了不存在的中点 | 改用顺序型映射 |
| 用顺序型映射来表示发散数据 | 掩盖“高于/低于中心”的差异 | 改用发散型映射,并对称设置 vmin/vmax |
发散型映射未设置 vmin/vmax | 中性色可能无法对齐 0 | 显式设置对称范围 |
| 类别太多却用顺序型映射 | 颜色相近难区分 | 使用定性映射(tab10, Set1) |
| 忽略色觉缺陷用户 | 约 8% 的男性读不懂你的图 | 使用 viridis、cividis 或用色盲模拟测试 |
FAQ
Matplotlib 中的 colormap 是什么?
Matplotlib 的 colormap 是一种把标量数值映射为颜色的函数。它接受 0 到 1 之间的值,并返回一个 RGBA 颜色元组。colormap 常用于 imshow、scatter、contourf、pcolormesh 等函数,通过颜色渐变来表达数据。你可以用 plt.colormaps['name'] 访问,或在 cmap 参数中传入名称字符串。
如何为数据选择合适的 colormap?
顺序数据(从低到高)使用 viridis、plasma 或 inferno。发散数据(相对中心偏离)使用 coolwarm 或 RdBu。分类数据使用 tab10 或 Set1。角度等循环数据使用 twilight。同时务必考虑可访问性——viridis 与 cividis 对色盲用户更安全。
如何在 Matplotlib 中创建自定义 colormap?
使用 matplotlib.colors.ListedColormap 可从指定颜色列表创建 colormap;使用 matplotlib.colors.LinearSegmentedColormap.from_list('name', colors) 可在锚点颜色之间创建平滑渐变。通过 plt.colormaps.register() 注册后即可按名称使用。
如何反转 Matplotlib 的 colormap?
在任何 colormap 名称后追加 _r 即可。例如 cmap='viridis_r' 是 viridis 的反转版,适用于所有内置 colormap。对于自定义 colormap,可以对 colormap 对象调用 .reversed() 方法。
为什么应该避免使用 jet colormap?
jet 存在感知不均匀问题,会制造虚假的边界并掩盖真实模式;对红绿色盲用户也不友好。Matplotlib 在 2.0 版本将默认 colormap 从 jet 改为 viridis,正是因为这些缺陷。建议使用 viridis、plasma 或 cividis。
如何给 Matplotlib 图添加 colorbar?
调用 plt.colorbar(mappable),其中 mappable 是 imshow、scatter、contourf 等函数返回的对象。可通过 label、orientation('horizontal'/'vertical')、shrink、pad 等参数进行自定义;也可以通过 cbar.ax 访问 colorbar 的轴对象做更细粒度控制。
总结
colormap 并不是装饰性的选择——它是功能组件,决定了你的可视化是在诚实传达信息,还是在误导读者。Matplotlib 提供了庞大的内置 colormap 库,并按四个清晰的类别组织(顺序型、发散型、定性、循环型),同时也提供了在需要时从零构建自定义 colormap 的工具。对任何顺序数据而言,感知均匀系列(viridis, plasma, inferno, magma, cividis)都应作为默认起点。对发散数据,选择 coolwarm 或 RdBu 等映射,并始终让中性色对齐到数据中具有意义的中心点。分类数据使用 tab10 或 Set1。同时永远要考虑受众——使用对色盲友好的 colormap 不是可选项,而是专业实践的一部分。