如何创建自定义colormap并解决colorbar扩展端颜色匹配问题
自定义Colormap颜色条扩展箭头颜色不符问题解决
问题说明
基于从图像提取的颜色-值字典创建与原图一致的自定义colormap,启用extend='both'后,颜色条上下扩展箭头区域颜色不符合预期,要求100对应的灰色显示在顶部箭头区域,底部匹配对应颜色。
提取的颜色-值字典
{ 100: "RGB(170, 170, 170)", 75: "RGB(90, 0, 0)", 50: "RGB(180, 0, 0)", 30: "RGB(255, 150, 0)", 20: "RGB(255, 250, 0)", 10:"RGB(0, 210, 0)", 5: "RGB(0, 120, 0)", 2.5: "RGB(70, 70, 200)", 1: "RGB(150, 150, 255)", 0.5: "RGB(220, 220, 255)", 0.1: "RGB(230, 230, 230)", 0:'RGB(255,255,255)' }
原实现代码
import numpy as np import matplotlib.pyplot as plt import matplotlib.colors as mcolors # Generate random data np.random.seed(42) # for reproducibility x, y, c = zip(*np.random.rand(30, 3) * 105 - 2) # Define the color dictionary color_dict = { 0: 'white', 0.1: "blue", 0.5: "pink", 1: "lightblue", 2.5: "blue", 5: "darkgreen", 10: "green", 20: "yellow", 30: "orange", 50: "red", 75: "brown", 100: "grey", 105: "grey" } cvals = list(color_dict.keys()) colors = list(color_dict.values()) cmap = mcolors.ListedColormap(colors) norm = mcolors.BoundaryNorm(boundaries=cvals, ncolors=len(colors)) plt.figure(figsize=(10, 6)) scatter = plt.scatter(x, y, c=c, cmap=cmap, norm=norm) cbar = plt.colorbar(scatter, extend='both') cbar.set_ticks(cvals[1:-1]) cbar.set_ticklabels([str(val) for val in cvals[1:-1]]) plt.title("Custom ListedColormap with Pointy Ends") plt.show()
效果对比图
预期效果:
当前问题效果:
解决方案
问题核心是ListedColormap默认不会将首尾颜色绑定到扩展区域,需手动指定over和under属性,同时修正颜色字典的顺序问题:
修改后的代码
import numpy as np import matplotlib.pyplot as plt import matplotlib.colors as mcolors # 生成随机数据 np.random.seed(42) x, y, c = zip(*np.random.rand(30, 3) * 105 - 2) # 使用提取的真实颜色字典 color_dict = { 0: "RGB(255,255,255)", 0.1: "RGB(230, 230, 230)", 0.5: "RGB(220, 220, 255)", 1: "RGB(150, 150, 255)", 2.5: "RGB(70, 70, 200)", 5: "RGB(0, 120, 0)", 10: "RGB(0, 210, 0)", 20: "RGB(255, 250, 0)", 30: "RGB(255, 150, 0)", 50: "RGB(180, 0, 0)", 75: "RGB(90, 0, 0)", 100: "RGB(170, 170, 170)" } # 按数值升序排序,确保边界与颜色顺序匹配 sorted_items = sorted(color_dict.items(), key=lambda item: item[0]) cvals = [item[0] for item in sorted_items] colors = [item[1] for item in sorted_items] # 创建Colormap并设置扩展区域颜色 cmap = mcolors.ListedColormap(colors) cmap.set_over(colors[-1]) # 顶部扩展箭头用最大值对应的灰色 cmap.set_under(colors[0]) # 底部扩展箭头用最小值对应的白色 # 创建边界归一化器 norm = mcolors.BoundaryNorm(boundaries=cvals, ncolors=len(colors)) # 绘制图形 plt.figure(figsize=(10, 6)) scatter = plt.scatter(x, y, c=c, cmap=cmap, norm=norm) cbar = plt.colorbar(scatter, extend='both') cbar.set_ticks(cvals) cbar.set_ticklabels([str(val) for val in cvals]) plt.title("Custom ListedColormap with Correct Extended Ends") plt.show()
关键修改点
- 对颜色字典按数值升序排序,避免因字典无序导致的颜色映射错误
- 通过
cmap.set_over()和cmap.set_under()直接指定扩展箭头区域的颜色 - 调整刻度设置,显示所有边界值,更清晰反映颜色映射区间
内容的提问来源于stack exchange,提问作者Samman Amgain
相关产品推荐
相关产品推荐

