如何用Matplotlib创建带指定刻度与颜色的色条并复现目标样式
解决Matplotlib色条白色位置与区间着色问题
问题根源
你当前用LinearSegmentedColormap做的是连续颜色映射,但你的需求是固定区间的离散/分段颜色映射——尤其是白色需要覆盖[-2.5, 2.5]的区间,而不是三个点的连续过渡,这就导致白色位置偏移、区间着色错误。
修正代码方案
1. 改用*BoundaryNorm*+*ListedColormap*实现分段着色
这是匹配你需求的正确方式,直接绑定区间边界和对应颜色:
import matplotlib.pyplot as plt import matplotlib.colors as mcolors # 原始区间边界 cvals = [-30, -25, -20, -15, -10, -7.5, -5, -2.5, 0, 2.5, 5, 7.5, 10, 15, 20, 25, 30] # 修正颜色数组:每个区间对应一个颜色,去掉重复的深蓝色(-30到-25区间仅需一个颜色) colors = ["#000080", "#3F00FF", "#1F51FF", "#0096FF", "#6495ED", "#00FFFF", "white", "#FAA0A0", "#F88379", "#FA8072", "#FA5F55", "#FF2400", "#80461B", "#7C3030"] # 创建分段归一化器(绑定区间边界)与色图(绑定区间对应颜色) norm = mcolors.BoundaryNorm(cvals, len(colors)) cmap = mcolors.ListedColormap(colors) # 测试生成色条 fig, ax = plt.subplots(figsize=(8, 1)) fig.subplots_adjust(bottom=0.5) cb = plt.colorbar(plt.cm.ScalarMappable(norm=norm, cmap=cmap), cax=ax, orientation='horizontal', ticks=cvals) plt.show()
2. 保留原颜色数组的兼容方案
如果你不想修改原始颜色数组,可直接复用原数据,只需调整色图与归一化器的绑定逻辑:
import matplotlib.pyplot as plt import matplotlib.colors as mcolors cvals = [-30, -25, -20, -15, -10, -7.5, -5, -2.5, 0, 2.5, 5, 7.5, 10, 15, 20, 25, 30] colors = ["#000080", "#000080", "#3F00FF", "#1F51FF", "#0096FF", "#6495ED", "#00FFFF", "white", "white", "white", "#FAA0A0", "#F88379", "#FA8072", "#FA5F55", "#FF2400", "#80461B", "#7C3030"] # 取前16个颜色对应16个区间(17个边界点划分16个区间) norm = mcolors.BoundaryNorm(cvals, len(cvals)-1) cmap = mcolors.ListedColormap(colors[:-1]) # 测试生成色条 fig, ax = plt.subplots(figsize=(8, 1)) fig.subplots_adjust(bottom=0.5) cb = plt.colorbar(plt.cm.ScalarMappable(norm=norm, cmap=cmap), cax=ax, orientation='horizontal', ticks=cvals) plt.show()
原方法失效原因
LinearSegmentedColormap是基于连续插值生成颜色映射,它会把你给出的(归一化后区间值, 颜色)对作为插值节点,自动在节点间生成过渡色。你给出了三个白色节点(-2.5、0、2.5),插值后会把白色从-2.5平滑过渡到2.5,但你实际需要的是该区间内完全纯色的白色,而非过渡效果,因此必须用分段映射方案。
图表着色验证
使用修正后的cmap和norm绘制图表时,只需在绘图函数(如imshow、scatter)中指定cmap=cmap和norm=norm,即可确保每个数值落入对应区间时显示正确颜色。
内容的提问来源于stack exchange,提问作者kdbaseball8
相关产品推荐
相关产品推荐

