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

Seaborn子图颜色不匹配及图例顺序调整问题求助

Seaborn子图颜色不一致与图例顺序调整方案

问题描述

  1. 箱线图与直方图设置了相同的调色板,但颜色仍存在细微差异,即使将直方图alpha设为1也无法解决;
  2. 希望图例中'Group A'显示在'Group B'上方,尝试hue_order和handles参数未成功。

原代码:

groupA = [94, 74, 65, 36, 32, 65, 56, 59, 24, 133, 16, 8, 18]
groupB = [1, 1, 1, 1, 2, 7, 7, 10, 15, 16, 17, 17, 19, 29, 31, 32, 43, 43, 44, 47, 56, 64, 64, 80, 81, 87, 103, 121, 121, 121, 187, 197, 236, 292, 319, 8, 12, 12, 14, 14, 15, 16, 16, 20, 20, 33, 36, 37, 37, 44, 46, 48, 51, 51, 54, 57, 72, 74, 95, 103, 103, 107, 134, 199, 216, 228, 254]
f, (ax_boxplot, ax_histogram) = plt.subplots(2, sharex=True, gridspec_kw={'height_ratios': (0.3,0.7)}, figsize=(10,10))
sns.boxplot(data=[groupA, groupB], ax=ax_boxplot, orient='h', palette=['green', 'silver'])
ax_boxplot.tick_params(axis='y', left=False, labelleft=False)
sns.histplot(data=[groupA, groupB], bins=34, binrange=(0,340), palette=['green', 'silver'], alpha=1, edgecolor='black')
ax_histogram.tick_params(axis='both', labelsize=18)
ax_histogram.legend(labels=['groupB', 'groupA'], fontsize=16, frameon=False)
plt.xlabel("Days", fontsize=24, labelpad=20)
plt.ylabel("Count", fontsize=24, labelpad=20)
sns.despine()

解决方案

1. 颜色不一致问题修复

  • 核心原因:直接传入列表数据时,boxplot和histplot对调色板的解析逻辑有差异,且颜色名称的渲染存在细微偏差。
  • 修复步骤:
    • 将数据整理为DataFrame,通过hue参数绑定分组,让两个图表共享同一颜色映射规则;
    • 使用精确的十六进制RGB颜色值,替代模糊的颜色名称,彻底消除渲染差异。

2. 图例顺序调整

  • 核心原因:原代码手动指定labels但未匹配对应图形元素,且未利用hue_order控制分组优先级。
  • 修复步骤:
    • 在两个绘图函数中设置hue_order=['Group A', 'Group B'],统一分组显示顺序;
    • 从直方图中获取自动生成的handles和labels,基于这些元素创建图例,确保顺序与hue_order一致;
    • 移除箱线图的图例,避免重复显示。

修改后完整代码

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

groupA = [94, 74, 65, 36, 32, 65, 56, 59, 24, 133, 16, 8, 18]
groupB = [1, 1, 1, 1, 2, 7, 7, 10, 15, 16, 17, 17, 19, 29, 31, 32, 43, 43, 44, 47, 56, 64, 64, 80, 81, 87, 103, 121, 121, 121, 187, 197, 236, 292, 319, 8, 12, 12, 14, 14, 15, 16, 16, 20, 20, 33, 36, 37, 37, 44, 46, 48, 51, 51, 54, 57, 72, 74, 95, 103, 103, 107, 134, 199, 216, 228, 254]

# 整理为结构化DataFrame
df = pd.DataFrame({
    'Days': groupA + groupB,
    'Group': ['Group A'] * len(groupA) + ['Group B'] * len(groupB)
})

# 创建子图
f, (ax_boxplot, ax_histogram) = plt.subplots(2, sharex=True, gridspec_kw={'height_ratios': (0.3, 0.7)}, figsize=(10, 10))

# 绘制箱线图:统一颜色与分组顺序
sns.boxplot(data=df, x='Days', y='Group', ax=ax_boxplot, orient='h',
            palette={'Group A': '#008000', 'Group B': '#C0C0C0'},
            hue_order=['Group A', 'Group B'])
ax_boxplot.tick_params(axis='y', left=False, labelleft=False)
ax_boxplot.legend_.remove()  # 移除箱线图图例,避免重复

# 绘制直方图:与箱线图保持一致的颜色和顺序
hist_plot = sns.histplot(data=df, x='Days', hue='Group', bins=34, binrange=(0, 340),
                         palette={'Group A': '#008000', 'Group B': '#C0C0C0'},
                         hue_order=['Group A', 'Group B'],
                         alpha=1, edgecolor='black', ax=ax_histogram)
ax_histogram.tick_params(axis='both', labelsize=18)

# 基于直方图的handles和labels创建正确顺序的图例
handles, labels = hist_plot.get_legend_handles_labels()
ax_histogram.legend(handles, labels, fontsize=16, frameon=False)

# 设置轴标签
plt.xlabel("Days", fontsize=24, labelpad=20)
plt.ylabel("Count", fontsize=24, labelpad=20)
sns.despine()
plt.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 16:12:03