环境声明

  • Python版本:Python 3.12+
  • 核心库:Matplotlib 3.9+, Seaborn 0.13+, NumPy 2.0+, colorspacious 1.1+
  • 适用平台:Windows / macOS / Linux

1. 色彩空间详解

色彩空间是描述和量化颜色的数学模型。理解不同色彩空间的特性,是数据可视化配色的基础。

1.1 RGB色彩空间

RGB(Red, Green, Blue)是加色模型,通过红、绿、蓝三原色的叠加产生各种颜色。

应用场景

  • 屏幕显示(显示器、投影仪)
  • 数字图像处理
  • Web设计与前端开发

取值范围:每个通道0-255(8位)或0.0-1.0(浮点)

import matplotlib.pyplot as plt
import numpy as np

# RGB颜色表示示例
rgb_red = (1.0, 0.0, 0.0)      # 纯红
rgb_green = (0.0, 1.0, 0.0)    # 纯绿
rgb_blue = (0.0, 0.0, 1.0)     # 纯蓝
rgb_white = (1.0, 1.0, 1.0)    # 白色
rgb_black = (0.0, 0.0, 0.0)    # 黑色

# 展示RGB颜色混合
fig, axes = plt.subplots(2, 2, figsize=(10, 8))
colors = [rgb_red, rgb_green, rgb_blue, (1.0, 1.0, 0.0)]
titles = ['Red (1,0,0)', 'Green (0,1,0)', 'Blue (0,0,1)', 'Yellow (1,1,0)']

for ax, color, title in zip(axes.flat, colors, titles):
    ax.add_patch(plt.Rectangle((0, 0), 1, 1, facecolor=color))
    ax.set_xlim(0, 1)
    ax.set_ylim(0, 1)
    ax.set_title(title)
    ax.axis('off')

plt.suptitle('RGB Color Space Examples', fontsize=14)
plt.tight_layout()
plt.savefig('rgb_colors.png', dpi=150, bbox_inches='tight')
plt.show()

1.2 CMYK色彩空间

CMYK(Cyan, Magenta, Yellow, Key/Black)是减色模型,主要用于印刷领域。

与RGB的区别

  • RGB是加色,越加越亮
  • CMYK是减色,越减越暗

应用场景

  • 印刷品设计
  • 出版物制作
  • 包装印刷

1.3 HSL色彩空间

HSL(Hue, Saturation, Lightness)更符合人类对颜色的感知方式。

分量 含义 取值范围
H (Hue) 色相 0-360度
S (Saturation) 饱和度 0-100%
L (Lightness) 亮度 0-100%

优势

  • 直观调整颜色属性
  • 便于生成配色方案
  • 支持语义化颜色操作
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import numpy as np

# HSL到RGB转换函数
def hsl_to_rgb(h, s, l):
    """将HSL转换为RGB"""
    s /= 100
    l /= 100
    c = (1 - abs(2 * l - 1)) * s
    x = c * (1 - abs((h / 60) % 2 - 1))
    m = l - c / 2
  
    if h < 60:
        r, g, b = c, x, 0
    elif h < 120:
        r, g, b = x, c, 0
    elif h < 180:
        r, g, b = 0, c, x
    elif h < 240:
        r, g, b = 0, x, c
    elif h < 300:
        r, g, b = x, 0, c
    else:
        r, g, b = c, 0, x
  
    return (r + m, g + m, b + m)

# 生成色相环
fig, ax = plt.subplots(figsize=(10, 10), subplot_kw=dict(projection='polar'))

n_colors = 36
for i in range(n_colors):
    hue = i * 10
    color = hsl_to_rgb(hue, 100, 50)
    theta = np.deg2rad(hue)
    ax.bar(theta, 1, width=np.deg2rad(10), color=color, edgecolor='white', linewidth=0.5)

ax.set_theta_zero_location('N')
ax.set_theta_direction(-1)
ax.set_yticks([])
ax.set_title('HSL Hue Wheel (Saturation=100%, Lightness=50%)', fontsize=14, pad=20)

plt.tight_layout()
plt.savefig('hsl_hue_wheel.png', dpi=150, bbox_inches='tight')
plt.show()

1.4 色彩空间对比

特性 RGB CMYK HSL
类型 加色模型 减色模型 感知模型
主要用途 屏幕显示 印刷 设计调色
人类友好度
设备依赖
色彩范围 广 窄(印刷限制) 理论全色域

2. 数据可视化配色类型

2.1 连续配色(Sequential)

用于表示有序数据,从低到高渐变。

适用场景

  • 温度分布
  • 人口密度
  • 销售额排名

设计原则

  • 使用单一色相
  • 亮度或饱和度渐变
  • 避免多色相干扰
import matplotlib.pyplot as plt
import numpy as np

# 连续配色方案展示
sequential_palettes = {
    'Blues': plt.cm.Blues,
    'Greens': plt.cm.Greens,
    'Oranges': plt.cm.Oranges,
    'Purples': plt.cm.Purples,
    'Greys': plt.cm.Greys
}

fig, axes = plt.subplots(len(sequential_palettes), 1, figsize=(10, 8))

for ax, (name, cmap) in zip(axes, sequential_palettes.items()):
    gradient = np.linspace(0, 1, 256).reshape(1, -1)
    ax.imshow(gradient, aspect='auto', cmap=cmap)
    ax.set_title(f'{name} - Sequential Palette', fontsize=11, loc='left')
    ax.set_xticks([])
    ax.set_yticks([])
    ax.spines['top'].set_visible(False)
    ax.spines['right'].set_visible(False)
    ax.spines['bottom'].set_visible(False)
    ax.spines['left'].set_visible(False)

plt.suptitle('Sequential Color Palettes for Ordered Data', fontsize=14)
plt.tight_layout()
plt.savefig('sequential_palettes.png', dpi=150, bbox_inches='tight')
plt.show()

2.2 离散配色(Diverging)

用于表示有明确中点的数据,向两侧发散。

适用场景

  • 温度偏差(相对于平均值)
  • 正负变化率
  • 满意度评分(以0为中点)

设计原则

  • 中性色作为中点
  • 两侧使用对比色相
  • 确保中点清晰可辨
import matplotlib.pyplot as plt
import numpy as np

# 离散配色方案展示
diverging_palettes = {
    'RdBu': plt.cm.RdBu_r,      # 红蓝对比
    'RdYlGn': plt.cm.RdYlGn,    # 红黄绿
    'PuOr': plt.cm.PuOr,        # 紫橙
    'BrBG': plt.cm.BrBG,        # 棕青
    'PiYG': plt.cm.PiYG         # 粉绿
}

fig, axes = plt.subplots(len(diverging_palettes), 1, figsize=(10, 8))

for ax, (name, cmap) in zip(axes, diverging_palettes.items()):
    gradient = np.linspace(0, 1, 256).reshape(1, -1)
    ax.imshow(gradient, aspect='auto', cmap=cmap)
    ax.set_title(f'{name} - Diverging Palette', fontsize=11, loc='left')
    ax.set_xticks([0, 128, 255])
    ax.set_xticklabels(['Low', 'Center', 'High'])
    ax.set_yticks([])

plt.suptitle('Diverging Color Palettes for Data with Critical Midpoint', fontsize=14)
plt.tight_layout()
plt.savefig('diverging_palettes.png', dpi=150, bbox_inches='tight')
plt.show()

2.3 分类配色(Qualitative)

用于表示无顺序的类别数据

适用场景

  • 产品类别
  • 地区划分
  • 部门分组

设计原则

  • 色相差异最大化
  • 避免亮度排序暗示
  • 控制颜色数量(建议不超过8种)
import matplotlib.pyplot as plt
import numpy as np

# 分类配色方案展示
qualitative_palettes = {
    'Set1': plt.cm.Set1,
    'Set2': plt.cm.Set2,
    'Set3': plt.cm.Set3,
    'Paired': plt.cm.Paired,
    'Dark2': plt.cm.Dark2
}

fig, axes = plt.subplots(1, len(qualitative_palettes), figsize=(15, 3))

for ax, (name, cmap) in zip(axes, qualitative_palettes.items()):
    n_colors = min(8, cmap.N)
    colors = [cmap(i / (n_colors - 1)) for i in range(n_colors)]
  
    for i, color in enumerate(colors):
        ax.add_patch(plt.Rectangle((i, 0), 0.9, 1, facecolor=color, edgecolor='white'))
  
    ax.set_xlim(0, n_colors)
    ax.set_ylim(0, 1)
    ax.set_title(name, fontsize=11)
    ax.axis('off')

plt.suptitle('Qualitative Color Palettes for Categorical Data', fontsize=14, y=1.05)
plt.tight_layout()
plt.savefig('qualitative_palettes.png', dpi=150, bbox_inches='tight')
plt.show()

3. 色盲类型与设计对策

3.1 色盲类型概览

全球约8%男性0.5%女性存在某种形式的色觉缺陷。

类型 占比 受影响颜色 特征
红色盲 1.3% 红-绿 无法区分红色和绿色
绿色盲 1.2% 红-绿 无法区分红色和绿色
蓝黄色盲 0.001% 蓝-黄 无法区分蓝色和黄色
全色盲 0.003% 所有颜色 仅能看到灰度

3.2 色盲模拟器实现

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle

# 色盲转换矩阵(基于LMS色彩空间)
COLORBLIND_MATRICES = {
    'normal': np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]),
    'protanopia': np.array([[0, 0.43333, 0], [0, 0.56667, 0], [0, 0, 1]]),  # 红色盲
    'deuteranopia': np.array([[0.625, 0.375, 0], [0.7, 0.3, 0], [0, 0.3, 0.7]]),  # 绿色盲
    'tritanopia': np.array([[1, 0, 0], [0, 0.5, 0.5], [0, 0.5, 0.5]]),  # 蓝黄色盲
}

def rgb_to_lms(rgb):
    """将RGB转换为LMS色彩空间"""
    rgb = np.array(rgb)
    # 转换到线性RGB
    linear_rgb = np.where(rgb <= 0.04045, rgb / 12.92, ((rgb + 0.055) / 1.055) ** 2.4)
    # LMS转换矩阵
    lms_matrix = np.array([
        [0.3138, 0.6395, 0.0467],
        [0.1551, 0.7579, 0.0870],
        [0.0172, 0.1095, 0.8733]
    ])
    return np.dot(lms_matrix, linear_rgb)

def lms_to_rgb(lms):
    """将LMS转换回RGB"""
    # 逆LMS矩阵
    rgb_matrix = np.array([
        [5.4722, -4.6419, 0.1697],
        [-1.1252, 2.1953, -0.0701],
        [0.0298, -0.1937, 1.1639]
    ])
    linear_rgb = np.dot(rgb_matrix, lms)
    # 转换回sRGB
    rgb = np.where(linear_rgb <= 0.0031308, linear_rgb * 12.92, 1.055 * (linear_rgb ** (1/2.4)) - 0.055)
    return np.clip(rgb, 0, 1)

def simulate_colorblind(rgb, colorblind_type='protanopia'):
    """模拟色盲视觉效果"""
    lms = rgb_to_lms(rgb)
    matrix = COLORBLIND_MATRICES.get(colorblind_type, COLORBLIND_MATRICES['normal'])
    lms_simulated = np.dot(matrix, lms)
    return lms_to_rgb(lms_simulated)

# 测试色盲模拟
test_colors = [
    (1.0, 0.0, 0.0),    # 红
    (0.0, 1.0, 0.0),    # 绿
    (0.0, 0.0, 1.0),    # 蓝
    (1.0, 1.0, 0.0),    # 黄
    (1.0, 0.0, 1.0),    # 洋红
    (0.0, 1.0, 1.0),    # 青
]

colorblind_types = ['normal', 'protanopia', 'deuteranopia', 'tritanopia']

fig, axes = plt.subplots(len(colorblind_types), len(test_colors), figsize=(14, 8))

for i, cb_type in enumerate(colorblind_types):
    for j, color in enumerate(test_colors):
        simulated = simulate_colorblind(color, cb_type)
        axes[i, j].add_patch(Rectangle((0, 0), 1, 1, facecolor=simulated))
        axes[i, j].set_xlim(0, 1)
        axes[i, j].set_ylim(0, 1)
        axes[i, j].axis('off')
      
        if i == 0:
            axes[i, j].set_title(f'RGB\n{tuple(round(c, 1) for c in color)}', fontsize=8)
        if j == 0:
            axes[i, j].text(-0.3, 0.5, cb_type, rotation=90, va='center', fontsize=10, fontweight='bold')

plt.suptitle('Color Blindness Simulation - How Colors Appear to Different Viewers', fontsize=14)
plt.tight_layout()
plt.savefig('colorblind_simulation.png', dpi=150, bbox_inches='tight')
plt.show()

3.3 色盲友好设计策略

核心原则

  1. 避免纯红绿对比:使用蓝橙、紫黄等替代方案
  2. 增加非色彩线索:形状、纹理、标签
  3. 使用色盲友好配色:ColorBrewer的色盲安全方案
  4. 测试验证:使用色盲模拟器检查

4. 暗色模式设计原则

4.1 暗色模式的优势

  • 减少眼部疲劳(低光环境)
  • 降低设备能耗(OLED屏幕)
  • 提升对比度感知
  • 现代UI设计趋势

4.2 暗色模式配色原则

元素 亮色模式 暗色模式
背景 白色 (#FFFFFF) 深灰 (#121212)
表面 浅灰 (#F5F5F5) 中灰 (#1E1E1E)
主文本 黑色 (#000000) 白色 (#FFFFFF)
次文本 深灰 (#666666) 浅灰 (#B3B3B3)
强调色 高饱和度 降低饱和度

4.3 自适应主题切换代码

import matplotlib.pyplot as plt
import matplotlib as mpl
from matplotlib.patches import Rectangle
import numpy as np

class ThemeManager:
    """主题管理器:支持亮色/暗色模式切换"""
  
    THEMES = {
        'light': {
            'background': '#FFFFFF',
            'surface': '#F5F5F5',
            'text_primary': '#212121',
            'text_secondary': '#757575',
            'grid': '#E0E0E0',
            'accent_colors': ['#1976D2', '#388E3C', '#F57C00', '#7B1FA2', '#C62828']
        },
        'dark': {
            'background': '#121212',
            'surface': '#1E1E1E',
            'text_primary': '#FFFFFF',
            'text_secondary': '#B3B3B3',
            'grid': '#333333',
            'accent_colors': ['#64B5F6', '#81C784', '#FFB74D', '#BA68C8', '#E57373']
        }
    }
  
    def __init__(self, theme='light'):
        self.current_theme = theme
        self.colors = self.THEMES[theme]
  
    def apply(self):
        """应用主题到matplotlib"""
        theme = self.colors
      
        plt.rcParams['figure.facecolor'] = theme['background']
        plt.rcParams['axes.facecolor'] = theme['surface']
        plt.rcParams['axes.edgecolor'] = theme['text_secondary']
        plt.rcParams['axes.labelcolor'] = theme['text_primary']
        plt.rcParams['text.color'] = theme['text_primary']
        plt.rcParams['xtick.color'] = theme['text_secondary']
        plt.rcParams['ytick.color'] = theme['text_secondary']
        plt.rcParams['grid.color'] = theme['grid']
        plt.rcParams['axes.prop_cycle'] = plt.cycler(color=theme['accent_colors'])
  
    def get_colors(self):
        """获取当前主题颜色"""
        return self.colors

# 演示主题切换效果
def create_sample_chart(theme_name, ax):
    """创建示例图表"""
    theme = ThemeManager(theme_name)
    colors = theme.get_colors()
  
    # 设置背景
    ax.set_facecolor(colors['surface'])
  
    # 生成示例数据
    x = np.linspace(0, 10, 100)
    for i, color in enumerate(colors['accent_colors'][:3]):
        y = np.sin(x + i) * (i + 1)
        ax.plot(x, y, color=color, linewidth=2, label=f'Series {i+1}')
  
    ax.set_xlabel('X Axis', color=colors['text_primary'])
    ax.set_ylabel('Y Axis', color=colors['text_primary'])
    ax.set_title(f'{theme_name.capitalize()} Mode Example', color=colors['text_primary'])
    ax.tick_params(colors=colors['text_secondary'])
    ax.legend(facecolor=colors['surface'], edgecolor=colors['grid'], 
              labelcolor=colors['text_primary'])
    ax.grid(True, alpha=0.3, color=colors['grid'])

# 创建对比图
fig, axes = plt.subplots(1, 2, figsize=(14, 5))

for ax, theme in zip(axes, ['light', 'dark']):
    create_sample_chart(theme, ax)
    theme_mgr = ThemeManager(theme)
    fig_patch = fig.patch
    if theme == 'dark':
        fig_patch.set_facecolor('#121212')

plt.tight_layout()
plt.savefig('theme_comparison.png', dpi=150, bbox_inches='tight', facecolor='white')
plt.show()

# 自适应系统主题检测
def detect_system_theme():
    """检测系统主题偏好(简化示例)"""
    import sys
    # Windows系统检测
    if sys.platform == 'win32':
        try:
            import winreg
            registry = winreg.ConnectRegistry(None, winreg.HKEY_CURRENT_USER)
            key = winreg.OpenKey(registry, r"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize")
            value, _ = winreg.QueryValueEx(key, "AppsUseLightTheme")
            return 'light' if value == 1 else 'dark'
        except:
            return 'light'
    return 'light'

print(f"Detected system theme: {detect_system_theme()}")

5. ColorBrewer配色方案应用

ColorBrewer是宾夕法尼亚州立大学开发的科学配色工具,提供经过验证的色盲友好配色方案。

import matplotlib.pyplot as plt
import numpy as np

# ColorBrewer配色方案定义
COLORBREWER_PALETTES = {
    # 连续配色
    'sequential': {
        'Blues': ['#F7FBFF', '#DEEBF7', '#C6DBEF', '#9ECAE1', '#6BAED6', '#4292C6', '#2171B5', '#08519C', '#08306B'],
        'Greens': ['#F7FCF5', '#E5F5E0', '#C7E9C0', '#A1D99B', '#74C476', '#41AB5D', '#238B45', '#006D2C', '#00441B'],
        'Oranges': ['#FFF5EB', '#FEE6CE', '#FDD0A2', '#FDAE6B', '#FD8D3C', '#F16913', '#D94801', '#A63603', '#7F2704'],
    },
    # 离散配色
    'diverging': {
        'RdBu': ['#B2182B', '#D6604D', '#F4A582', '#FDDBC7', '#F7F7F7', '#D1E5F0', '#92C5DE', '#4393C3', '#2166AC'],
        'RdYlGn': ['#D73027', '#F46D43', '#FDAE61', '#FEE08B', '#FFFFBF', '#D9EF8B', '#A6D96A', '#66BD63', '#1A9850'],
        'PuOr': ['#B35806', '#E08214', '#FDB863', '#FEE0B6', '#F7F7F7', '#D8DAEB', '#B2ABD2', '#8073AC', '#542788'],
    },
    # 分类配色(色盲友好)
    'qualitative': {
        'Set1': ['#E41A1C', '#377EB8', '#4DAF4A', '#984EA3', '#FF7F00', '#FFFF33', '#A65628', '#F781BF'],
        'Set2': ['#66C2A5', '#FC8D62', '#8DA0CB', '#E78AC3', '#A6D854', '#FFD92F', '#E5C494', '#B3B3B3'],
        'Dark2': ['#1B9E77', '#D95F02', '#7570B3', '#E7298A', '#66A61E', '#E6AB02', '#A6761D', '#666666'],
    }
}

def plot_colorbrewer_palettes():
    """可视化ColorBrewer配色方案"""
    fig, axes = plt.subplots(3, 3, figsize=(14, 10))
  
    categories = ['sequential', 'diverging', 'qualitative']
  
    for i, category in enumerate(categories):
        palettes = COLORBREWER_PALETTES[category]
        for j, (name, colors) in enumerate(list(palettes.items())[:3]):
            ax = axes[i, j]
          
            # 绘制颜色条
            for k, color in enumerate(colors):
                ax.add_patch(plt.Rectangle((k, 0), 1, 1, facecolor=color, edgecolor='white'))
          
            ax.set_xlim(0, len(colors))
            ax.set_ylim(0, 1)
            ax.set_title(f'{category.capitalize()}: {name}', fontsize=10)
            ax.axis('off')
  
    plt.suptitle('ColorBrewer Color Palettes - Scientifically Designed for Data Visualization', fontsize=14)
    plt.tight_layout()
    plt.savefig('colorbrewer_palettes.png', dpi=150, bbox_inches='tight')
    plt.show()

plot_colorbrewer_palettes()

# 实际应用示例:使用ColorBrewer配色绘制图表
def apply_colorbrewer_palette(ax, palette_name='Set2', n_colors=5):
    """应用ColorBrewer配色到图表"""
    # 从分类配色中获取
    colors = COLORBREWER_PALETTES['qualitative'].get(palette_name, COLORBREWER_PALETTES['qualitative']['Set2'])
    ax.set_prop_cycle(color=colors[:n_colors])

# 示例:多系列折线图
fig, ax = plt.subplots(figsize=(10, 6))
apply_colorbrewer_palette(ax, 'Dark2', 5)

x = np.linspace(0, 10, 100)
for i in range(5):
    y = np.sin(x + i * 0.5) * (1 + i * 0.2)
    ax.plot(x, y, linewidth=2.5, label=f'Category {chr(65+i)}')

ax.set_xlabel('Time', fontsize=11)
ax.set_ylabel('Value', fontsize=11)
ax.set_title('Multi-Series Chart with ColorBrewer Dark2 Palette', fontsize=13)
ax.legend(loc='upper right', framealpha=0.9)
ax.grid(True, alpha=0.3)

plt.tight_layout()
plt.savefig('colorbrewer_application.png', dpi=150, bbox_inches='tight')
plt.show()

6. 5组配色方案对比示例

import matplotlib.pyplot as plt
import numpy as np

# 定义5组不同的配色方案
PALETTES = {
    'Default': plt.cm.tab10.colors[:5],
    'ColorBrewer Set2': ['#66C2A5', '#FC8D62', '#8DA0CB', '#E78AC3', '#A6D854'],
    'Vibrant': ['#E74C3C', '#3498DB', '#2ECC71', '#F39C12', '#9B59B6'],
    'Pastel': ['#FFB3BA', '#BAFFC9', '#BAE1FF', '#FFFFBA', '#FFDFBA'],
    'Corporate': ['#003F5C', '#2F4B7C', '#665191', '#A05195', '#D45087'],
    'Nature': ['#264653', '#2A9D8F', '#E9C46A', '#F4A261', '#E76F51']
}

def create_comparison_chart():
    """创建配色方案对比图"""
    fig, axes = plt.subplots(2, 3, figsize=(15, 10))
    axes = axes.flatten()
  
    # 示例数据
    categories = ['Product A', 'Product B', 'Product C', 'Product D', 'Product E']
    values = [23, 45, 56, 78, 32]
    x = np.arange(len(categories))
  
    for idx, (name, colors) in enumerate(PALETTES.items()):
        ax = axes[idx]
      
        # 绘制柱状图
        bars = ax.bar(categories, values, color=colors, edgecolor='white', linewidth=1)
      
        # 设置标题
        ax.set_title(f'{name}', fontsize=12, fontweight='bold')
        ax.set_ylabel('Sales (K)', fontsize=10)
      
        # 添加数值标签
        for bar, val in zip(bars, values):
            height = bar.get_height()
            ax.text(bar.get_x() + bar.get_width()/2., height,
                   f'{val}',
                   ha='center', va='bottom', fontsize=9)
      
        # 旋转x轴标签
        ax.tick_params(axis='x', rotation=15)
  
    # 隐藏多余的子图
    axes[-1].axis('off')
  
    plt.suptitle('Color Palette Comparison - Same Data, Different Feelings', fontsize=14)
    plt.tight_layout()
    plt.savefig('palette_comparison.png', dpi=150, bbox_inches='tight')
    plt.show()

create_comparison_chart()

# 配色方案适用场景分析
fig, ax = plt.subplots(figsize=(12, 6))
ax.axis('off')

scenarios = [
    ['配色方案', '适用场景', '情感传达', '最佳用途'],
    ['Default', '通用场景', '中性、标准', '快速原型、默认展示'],
    ['ColorBrewer Set2', '学术报告', '专业、柔和', '论文图表、科研展示'],
    ['Vibrant', '营销材料', '活力、醒目', '广告、社交媒体'],
    ['Pastel', '女性产品', '温柔、优雅', '美妆、生活方式'],
    ['Corporate', '商务汇报', '稳重、可信', '企业年报、金融数据'],
    ['Nature', '环保主题', '自然、和谐', '生态、健康产品']
]

# 创建表格
table = ax.table(cellText=scenarios[1:], colLabels=scenarios[0],
                cellLoc='left', loc='center',
                colColours=['#4472C4']*4)

# 设置表格样式
table.auto_set_font_size(False)
table.set_fontsize(10)
table.scale(1.2, 2)

# 设置表头颜色
for i in range(4):
    table[(0, i)].set_text_props(color='white', fontweight='bold')

plt.title('Color Palette Selection Guide', fontsize=14, fontweight='bold', pad=20)
plt.savefig('palette_guide.png', dpi=150, bbox_inches='tight')
plt.show()

7. 避坑小贴士

常见错误

错误1:使用彩虹配色

  • 问题:彩虹色没有自然的感知顺序
  • 解决:改用连续配色或离散配色

错误2:颜色过多

  • 问题:超过8种颜色难以区分
  • 解决:合并小类别,使用其他视觉编码(形状、大小)

错误3:低对比度

  • 问题:背景与前景对比不足
  • 解决:确保对比度至少4.5:1(WCAG AA标准)

错误4:仅依赖颜色传达信息

  • 问题:色盲用户无法区分
  • 解决:同时使用形状、纹理、标签

错误5:忽略文化差异

  • 问题:颜色含义因文化而异
  • 解决:了解目标受众的文化背景

8. 前沿关联:AI辅助配色

2025年,AI配色技术正在快速发展:

技术趋势

  • 大语言模型配色:通过自然语言描述生成配色方案
  • 情感感知配色:根据数据情感自动调整色调
  • 品牌一致性:AI学习品牌指南,自动生成符合规范的配色

Python生态工具

# 使用AI配色API示例(概念代码)
def ai_generate_palette(description, n_colors=5):
    """
    基于描述生成配色方案
    示例:ai_generate_palette('科技感、冷静、专业', 5)
    """
    # 实际应用中可调用OpenAI API或专用配色服务
    # 这里展示概念实现
    pass

实用建议

  • AI配色作为起点,人工微调
  • 始终进行色盲测试
  • 保持品牌一致性

9. 一句话总结

好的数据可视化配色,是让数据自己说话的艺术——它应该 invisible(隐形地引导视线),而非 eye-catching(喧宾夺主地吸引注意)。


Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐