本系列文章配套代码获取有以下两种途径:
-
通过百度网盘获取:
链接:https://pan.baidu.com/s/1jG-rGG4QMuZu0t0kEEl7SA?pwd=mnsj
提取码:mnsj
-
前往GitHub获取:
https://github.com/returu/Data_Visualization

使用示例:
另外,当使用色彩映射图时,一般会增加色彩条Colorbar,其作用是把 colormap 的“数值↔颜色”对应关系可视化,作为图例放在图的旁边。
# 创建一些示例数据
data = np.random.randn(10, 10) # 10x10 的随机数据
x = np.random.rand(100)
y = np.random.rand(100)
z = np.random.rand(100) * 100 # 颜色值
# 创建子图
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
# 示例 1: 使用 imshow 绘制二维数组
im = ax1.imshow(data, cmap='viridis') # 通过cmap参数指定色彩映射为viridis
ax1.set_title('2D Array with Viridis Colormap')
fig.colorbar(im, ax=ax1) # 添加颜色条,它从 im 获取 cmap 信息
# 示例 2: 使用 scatter 绘制散点图,点的大小颜色由 z 决定
sc = ax2.scatter(x, y, c=z, cmap='plasma', s=50, alpha=0.7) # 通过cmap参数指定色彩映射为plasma
ax2.set_title('Scatter Plot with Plasma Colormap')
fig.colorbar(sc, ax=ax2) # 为散点图添加颜色条
plt.tight_layout()
plt.show()

选择和获取Colormap:
-
查看所有可用的 Colormap:
# 获得全部可用的颜色映射表
plt.colormaps()
-
连续型(Sequential):
用于表示从低到高有序的数据(如温度、海拔、密度)。颜色从亮到暗或从浅到深变化。例如 viridis
, plasma
, inferno
, magma
, cividis
。

-
发散型(Diverging):
用于表示具有一个明显中间值(如零)或临界值的数据,数据向两端发散(如温度异常、盈利与亏损)。中间通常是亮色,两端是两种对比鲜明的深色。例如 RdBu
, PiYG
, coolwarm
, bwr
。

-
循环型(Cyclic):
用于表示循环或周期性的数据(如角度、风向、相位)。起点和终点的颜色相同。例如 twilight
, hsv
。

-
定性型(Qualitative):
用于表示分类或无序的数据。颜色之间变化明显,但没有亮度或色度的顺序。例如 tab10
, Set1
, Pastel1
。

因素 |
建议 |
数据性质 |
连续有序 → Sequential;带零点的偏差 → Diverging |
直觉认知 |
水深用蓝、高温用红,符合读者预期 |
领域惯例 |
气象雷达常用 nipy_spectral,医学影像常用 gray |
感知均匀 |
人眼对亮度变化最敏感,优先选亮度单调递增的 colormap(如 viridis) |
https://matplotlib.org/stable/users/explain/colors/colormaps.html
-
获取 Colormap 对象:
# 方法 1: 使用 plt.get_cmap(),推荐
plt.get_cmap('hsv')
# 方法 2: 使用 matplotlib.cm 模块
plt.cm.hsv

x = np.linspace(0 , 3*np.pi , 500)
N = 20
# 循环绘制N条正弦曲线
for i in range(N):
# 通过 c=plt.cm.hsv(i/N) 设置曲线颜色,使用HSV颜色映射,
# 随着i从0到N-1变化,i/N从0到1变化,实现颜色平滑过渡
plt.plot(x , i*np.sin(x) , c=plt.cm.hsv(i/N))
print(plt.cm.hsv(i/N))
plt.show()
# 输出:
# (1.0, 0.0, 0.0, 1.0)
# (1.0, 0.2779414544120426, 0.0, 1.0)
# ......
# (1.0, 0.0, 0.6727946966917553, 1.0)
# (1.0, 0.0, 0.37169145441204254, 1.0)

-
反转 Colormap:
在任何 colormap 名称后加上 _r 即可获得其反转色彩版本,比如 “viridis_r” 会让原本的低值颜色对应高值。
x = np.linspace(0 , 3*np.pi , 500)
y1 = x
y2 = -x
plt.scatter(x , y1 , c=x , cmap='magma' , lw=10)
plt.scatter(x , y2 , c=x , cmap='magma_r' , lw=10) # 反转 Colormap
plt.show()

裁剪Colormap范围:
在 Matplotlib 中,我们可以使用多种方法来裁剪 Colormap 的范围,以便更好地可视化数据,只显示特定范围内的数据,其余颜色会被裁剪到边界值。这在可视化时非常有用,可以突出显示我们关心的数据范围。
-
使用vmin和vmax参数:直接设置颜色映射的最小值和最大值,超出范围的数据会被裁剪或压缩到边界颜色。该方法是最直接的方法,在调用绘图函数时直接指定颜色范围。 -
使用clim函数:与 vmin/vmax 功能相同,是 Axes 对象的方法,用于设置 colorbar 的显示范围。该方法适用于已经创建的图像对象,可以动态调整颜色范围。 -
使用 plt.Normalize(vmin, vmax):创建一个归一化对象,用于将数据映射到 [0, 1] 区间,从而控制颜色映射的范围。该方法提供最大的灵活性,可以创建自定义的标准化对象。另外,plt.Normalize与matplotlib.colors.Normalize 二者功能没有差异,只是调用方式不同。
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
from matplotlib.colors import Normalize
# 创建示例数据
np.random.seed(42)
data = np.random.randn(10, 10) * 2 + 5 # 均值为5,标准差为2的正态分布数据
# 创建图形和子图
fig, axes = plt.subplots(2, 2, figsize=(10, 8))
fig.suptitle('Colormap范围裁剪方法比较', fontsize=16)
# 1. 原始数据 - 无范围限制
im1 = axes[0, 0].imshow(data, cmap='viridis')
axes[0, 0].set_title('原始数据 (无范围限制)')
plt.colorbar(im1, ax=axes[0, 0])
# 2. 使用vmin/vmax参数
im2 = axes[0, 1].imshow(data, cmap='viridis', vmin=3, vmax=7)
axes[0, 1].set_title('使用vmin/vmax (3-7)')
plt.colorbar(im2, ax=axes[0, 1])
# 3. 使用clim()函数
im3 = axes[1, 0].imshow(data, cmap='viridis')
im3.set_clim(3, 7) # 设置颜色范围
axes[1, 0].set_title('使用clim() (3-7)')
plt.colorbar(im3, ax=axes[1, 0])
# 4. 使用plt.Normalize
norm = Normalize(vmin=3, vmax=7) # 创建标准化对象
im4 = axes[1, 1].imshow(data, cmap='viridis', norm=norm)
axes[1, 1].set_title('使用Normalize (3-7)')
plt.colorbar(im4, ax=axes[1, 1])
plt.tight_layout()
plt.show()

创建自定义Colormap:
-
使用LinearSegmentedColormap:
LinearSegmentedColormap 允许通过定义颜色在特定位置的值来创建自定义渐变。
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap
# 1. 构造颜色字典
cdict = {
'red': [(0.0, 0.1, 0.1), # 起点
(0.35, 0.3, 0.3), # 控制点 1
(0.65, 0.9, 0.9), # 控制点 2
(1.0, 0.9, 0.9)], # 终点
'green': [(0.0, 0.2, 0.2),
(0.35, 0.7, 0.7),
(0.65, 0.7, 0.7),
(1.0, 0.1, 0.1)],
'blue': [(0.0, 0.9, 0.9),
(0.35, 0.9, 0.9),
(0.65, 0.3, 0.3),
(1.0, 0.1, 0.1)]
}
# 平滑度
n_bins = 100
cmap = LinearSegmentedColormap('myBlueRed', cdict, N=n_bins)
# 2. 可视化
x = np.linspace(0, 1, 512).reshape(1, -1)
fig, ax = plt.subplots(figsize=(6, 1))
ax.imshow(x, aspect='auto', cmap=cmap)
ax.set_axis_off()
plt.show()
可视化结果如下图所示:

-
使用ListedColormap:
ListedColormap 适用于创建由特定颜色列表组成的离散 Colormap。
# ---------- 自定义纯色离散 ----------
colors = ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd', '#8c564b', '#e377c2']
cmap1 = ListedColormap(colors)
# ---------- 把连续 colormap 截断成离散 ----------
base = plt.cm.get_cmap('viridis', 256)
discrete = base(np.linspace(0, 1, 7)) # 只取 7 个节点
cmap2 = ListedColormap(discrete)
# ---------- 可视化 ----------
fig, ax = plt.subplots(1, 2, figsize=(8, 1.2))
# 可视化 cmap1
gradient1 = np.linspace(0, 1, 256).reshape(1, -1)
ax[0].imshow(gradient1, aspect='auto', cmap=cmap1)
ax[0].set_title('cmap1 (纯色离散)')
ax[0].set_axis_off()
# 可视化 cmap2
gradient2 = np.linspace(0, 1, 256).reshape(1, -1)
ax[1].imshow(gradient2, aspect='auto', cmap=cmap2)
ax[1].set_title('cmap2 (viridis 离散)')
ax[1].set_axis_off()
plt.tight_layout()
plt.show()
可视化结果如下图所示:

-
两者嵌套使用:
from matplotlib.colors import LinearSegmentedColormap, ListedColormap
# ---------- 第一段:LinearSegmentedColormap ----------
cdict_cold2green = {
'red': [(0.0, 0.0, 0.0),
(1.0, 0.0, 0.0)],
'green': [(0.0, 0.1, 0.1),
(1.0, 0.8, 0.8)],
'blue': [(0.0, 0.8, 0.8),
(1.0, 0.1, 0.1)]
}
cmap1 = LinearSegmentedColormap('cold2green', cdict_cold2green)
# ---------- 第二段:离散 ListedColormap ----------
disc_colors = plt.cm.get_cmap('tab10', 7)(np.linspace(0.3, 0.9, 7))
cmap2 = ListedColormap(disc_colors)
# ---------- 第三段:LinearSegmentedColormap----------
cdict_hot = {
'red': [(0.0, 0.5, 0.5), (1.0, 1.0, 1.0)],
'green': [(0.0, 0.3, 0.3), (1.0, 0.2, 0.2)],
'blue': [(0.0, 0.0, 0.0), (1.0, 0.1, 0.1)]
}
cmap3 = LinearSegmentedColormap('hot_gamma', cdict_hot)
# ---------- 合并三段 ----------
# 每段各占比例 0.4, 0.3, 0.3
N1, N2, N3 = 256, 192, 192
colors = np.vstack([cmap1(np.linspace(0, 1, N1)),
cmap2(np.linspace(0, 1, N2)),
cmap3(np.linspace(0, 1, N3))])
cmap_final = ListedColormap(colors, name='triple')
# ---------- 可视化 ----------
gradient = np.linspace(0, 1, 640).reshape(1, -1)
fig, ax = plt.subplots(figsize=(8, 1.2))
ax.imshow(gradient, aspect='auto', cmap=cmap_final)
ax.set_axis_off()
plt.show()

更多内容可以前往官网查看:
https://matplotlib.org/stable/


本篇文章来源于微信公众号: 码农设计师