如何编写适配色盲人群的连续调色板代码?
适配色盲人群的连续调色板实现(以目标调色板为例)
核心思路
色盲人群(尤其是占比最高的红绿色盲)对红、绿色系区分度极低,因此要优先选择蓝-黄/橙这类跨色轴的渐变——这类颜色在色盲视觉中差异明显。复现目标调色板的核心步骤是:
- 提取目标渐变的起始/结束色值
- 在感知均匀的颜色空间中插值,保证渐变连续且区分度一致
- 验证调色板的色盲友好性
步骤1:提取目标调色板的关键色值
用系统自带取色器、GIMP等工具打开目标图片,获取渐变两端的RGB值。从图中可提取到参考锚点:
- 深色端点:
RGB(0, 48, 73) - 浅色端点:
RGB(237, 125, 49)
若需要更精准的渐变效果,还可以提取多个中间锚点加入调色板定义。
步骤2:用Python生成连续调色板
方案1:快速实现(RGB线性插值)
借助matplotlib的LinearSegmentedColormap直接构建自定义调色板:
import matplotlib.pyplot as plt from matplotlib.colors import LinearSegmentedColormap # 锚点RGB值归一到0-1区间 colors = [ (0/255, 48/255, 73/255), # 深蓝 (237/255, 125/255, 49/255) # 浅橙 ] # 创建256阶连续调色板 custom_cmap = LinearSegmentedColormap.from_list("colorblind_friendly", colors, N=256) # 可视化调色板 plt.imshow([list(range(256))], cmap=custom_cmap, aspect='auto') plt.axis('off') plt.show()
方案2:感知均匀插值(更自然)
直接RGB插值可能在人眼(包括色盲)看来渐变不均匀,推荐在CIELAB空间插值,用colorspacious库实现:
from colorspacious import cspace_convert import numpy as np import matplotlib.pyplot as plt from matplotlib.colors import LinearSegmentedColormap # 定义RGB锚点(0-255范围) rgb_anchors = np.array([[0, 48, 73], [237, 125, 49]]) # 转换为CIELAB感知空间 lab_anchors = cspace_convert(rgb_anchors, "sRGB1", "CIELab") # 生成256个插值点 num_colors = 256 lab_values = np.linspace(lab_anchors[0], lab_anchors[1], num_colors) # 转换回RGB并截断到0-1区间 rgb_values = np.clip(cspace_convert(lab_values, "CIELab", "sRGB1"), 0, 1) # 创建调色板 custom_cmap = LinearSegmentedColormap.from_list("colorblind_friendly_lab", rgb_values, N=num_colors) # 可视化 plt.imshow([list(range(num_colors))], cmap=custom_cmap, aspect='auto') plt.axis('off') plt.show()
步骤3:验证色盲友好性
用colorspacious模拟红绿色盲(红色盲Protanopia、绿色盲Deuteranopia)的视觉效果,检查渐变是否依然有清晰区分度:
# 转换为色盲模拟后的颜色 rgb_protanopia = cspace_convert(rgb_values, "sRGB1", {"name": "protanopia", "severity": 1.0}) rgb_deuteranopia = cspace_convert(rgb_values, "sRGB1", {"name": "deuteranopia", "severity": 1.0}) # 绘制对比图 fig, (ax1, ax2, ax3) = plt.subplots(3, 1, figsize=(10, 3)) ax1.imshow([list(range(num_colors))], cmap=custom_cmap, aspect='auto') ax1.set_title("正常视觉") ax1.axis('off') ax2.imshow([list(range(num_colors))], cmap=LinearSegmentedColormap.from_list("protanopia", rgb_protanopia, N=num_colors), aspect='auto') ax2.set_title("红色盲(Protanopia)模拟") ax2.axis('off') ax3.imshow([list(range(num_colors))], cmap=LinearSegmentedColormap.from_list("deuteranopia", rgb_deuteranopia, N=num_colors), aspect='auto') ax3.set_title("绿色盲(Deuteranopia)模拟") ax3.axis('off') plt.tight_layout() plt.show()
额外实用建议
- 避免使用红-绿色系渐变,优先选择蓝-黄、蓝-橙、灰阶+单一彩色这类组合
- 可直接使用成熟的色盲友好调色板,比如
seaborn的colorblind、matplotlib的viridis/plasma(均经过色盲友好验证) - 若需高度还原目标调色板,可提取原图中更多锚点颜色,插值时加入这些点优化渐变效果
内容的提问来源于stack exchange,提问作者Renan Andrade
相关产品推荐
相关产品推荐

