如何用Matplotlib创建基于特定值定义颜色的线性颜色映射?
实现自定义线性颜色映射(指定值对应颜色平滑渐变)
问题背景
需要创建一个颜色映射,让数据在指定的数值点之间呈现线性平滑渐变。现有代码尝试用ListedColormap+BoundaryNorm实现,但得到的是离散色块而非平滑渐变:
import numpy as np import matplotlib as mpl import matplotlib.pyplot as plt data = np.random.uniform(0, 10, (10, 10)) values = [0., 0.8, 1., 10.] colors = ["#ff0000", "#00ff00", "#0000ff", "#cccccc"] # 错误尝试:生成离散色块 cmap = mpl.colors.ListedColormap(colors, name="mycmap") norm = mpl.colors.BoundaryNorm(values, len(colors)) fig, axe = plt.subplots() cmap_ = axe.imshow(data, aspect="auto", origin="upper", cmap=cmap, norm=norm) cbar = fig.colorbar(cmap_, ax=axe) plt.show()
解决方案
ListedColormap+BoundaryNorm是用于生成离散颜色区间的组合,要实现平滑渐变,需用LinearSegmentedColormap创建连续颜色映射,配合常规的Normalize归一化:
正确代码
import numpy as np import matplotlib as mpl import matplotlib.pyplot as plt data = np.random.uniform(0, 10, (10, 10)) values = [0., 0.8, 1., 10.] colors = ["#ff0000", "#00ff00", "#0000ff", "#cccccc"] # 1. 创建归一化对象,将数据映射到我们定义的数值范围 norm = mpl.colors.Normalize(vmin=values[0], vmax=values[-1]) # 2. 将每个指定数值转换为0-1之间的归一化位置 normed_points = [norm(v) for v in values] # 3. 创建线性分段颜色映射,指定每个归一化位置对应的颜色 cmap = mpl.colors.LinearSegmentedColormap.from_list("mycmap", list(zip(normed_points, colors))) # 绘图 fig, axe = plt.subplots() im = axe.imshow(data, aspect="auto", origin="upper", cmap=cmap, norm=norm) cbar = fig.colorbar(im, ax=axe) plt.show()
原理说明
Normalize:确保原始数据被正确映射到我们定义的values范围(0到10),转换为0-1之间的归一化值。LinearSegmentedColormap.from_list:通过指定归一化位置-颜色的对应关系,在每一对相邻的指定数值之间生成线性渐变的颜色过渡,最终得到连续平滑的颜色映射。
内容的提问来源于stack exchange,提问作者jlandercy
相关产品推荐
相关产品推荐

