You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Barplot标签与背景对比度优化:求颜色明暗判断函数

这个场景太常见了!我做可视化的时候也经常被浅背景下的白色标签可读性问题困扰。刚好可以借助WCAG(Web内容无障碍指南)里的相对亮度计算规则,写一个自动判断背景明暗、返回对应黑白标签色的函数,完美解决对比度问题。

核心思路:基于相对亮度的对比度判断

WCAG 2.0标准定义了相对亮度的计算方法,用来衡量颜色的明暗程度。当背景的相对亮度超过0.5时,黑色文本与背景的对比度能达到至少4.5:1(符合无障碍要求);反之,白色文本的对比度更优。我们就基于这个阈值来切换标签颜色。

实现函数(Python版本)

这个函数支持两种输入格式:十六进制颜色字符串(如#f5f5f5)或RGB元组(如(245,245,245)),输出对应的黑色或白色十六进制颜色:

def get_contrast_text_color(background_color):
    # 处理输入格式:支持十六进制或RGB元组
    if isinstance(background_color, str):
        # 去除#号,解析十六进制为RGB值
        bg_hex = background_color.lstrip('#')
        r, g, b = tuple(int(bg_hex[i:i+2], 16) for i in (0, 2, 4))
    elif isinstance(background_color, tuple) and len(background_color) == 3:
        r, g, b = background_color
    else:
        raise ValueError("请输入有效的十六进制颜色(如#ffffff)或RGB元组(如(255,255,255))")
    
    # 将RGB值转换为0-1范围
    r_norm = r / 255.0
    g_norm = g / 255.0
    b_norm = b / 255.0
    
    # 按照WCAG标准线性化RGB通道值
    def linearize_channel(v):
        if v <= 0.03928:
            return v / 12.92
        else:
            return ((v + 0.055) / 1.055) ** 2.4
    
    r_lin = linearize_channel(r_norm)
    g_lin = linearize_channel(g_norm)
    b_lin = linearize_channel(b_norm)
    
    # 计算相对亮度
    relative_luminance = 0.2126 * r_lin + 0.7152 * g_lin + 0.0722 * b_lin
    
    # 根据亮度阈值返回文本颜色
    return '#000000' if relative_luminance > 0.5 else '#ffffff'
函数说明
  • 输入处理:自动兼容两种常用的颜色表示方式,不需要额外转换
  • 亮度计算:严格遵循WCAG标准,确保对比度符合无障碍设计要求
  • 阈值逻辑:0.5的阈值是经过验证的平衡点,能保证文本在任何背景下都清晰可读
实际使用示例(Matplotlib Barplot)

把这个函数用到你的barplot里,自动设置标签颜色:

import matplotlib.pyplot as plt

# 示例数据
bar_colors = ['#f0f0f0', '#2d3748', '#ffcc00', '#663399']
labels = ['类别A', '类别B', '类别C', '类别D']
values = [18, 25, 12, 22]

fig, ax = plt.subplots()
bars = ax.bar(labels, values, color=bar_colors)

# 为每个柱子添加数值标签,并自动匹配文本颜色
for bar in bars:
    height = bar.get_height()
    # 获取柱子的背景颜色(Matplotlib返回RGBA,取前三个通道转RGB元组)
    bg_rgb = tuple(int(channel * 255) for channel in bar.get_facecolor()[:3])
    text_color = get_contrast_text_color(bg_rgb)
    
    # 添加标签
    ax.text(
        bar.get_x() + bar.get_width() / 2,
        height,
        f'{height}',
        ha='center', va='bottom',
        fontsize=12, color=text_color
    )

plt.title('自动适配对比度的Barplot')
plt.show()

运行这段代码后,每个柱子的标签颜色都会自动根据背景调整:浅背景用黑色,深背景用白色,完全解决可读性问题。

内容的提问来源于stack exchange,提问作者SkyWalker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:34:14