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

如何为多层表头DataFrame绘制指定格式的柱状图?

双层表头DataFrame的柱状图绘制方案

数据转换优化

你用df.T.melt(ignore_index=False)的方向没问题,但需要调整转换逻辑,让数据结构更适配绘图需求。先把原始双层表头的DataFrame转成长格式,完整保留层级信息:

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

# 构造原始DataFrame
data = {('Case1', 'A'): {'One': 0.96396415, 'Two': 0.832049574, 'Three': 0.636568627, 'Four': 0.765846157},('Case1', 'B'): {'One': 0.257496625, 'Two': 0.984418254, 'Three': 0.018891398, 'Four': 0.440278509},('Case1', 'C'): {'One': 0.512732941, 'Two': 0.622697929, 'Three': 0.731555346, 'Four': 0.031419349},('Case2', 'A'): {'One': 0.736783294, 'Two': 0.460765675, 'Three': 0.078558864, 'Four': 0.566186283},('Case2', 'B'): {'One': 0.921473211, 'Two': 0.274749932, 'Three': 0.312766018, 'Four': 0.159229808},('Case2', 'C'): {'One': 0.146389032, 'Two': 0.893299471, 'Three': 0.536288712, 'Four': 0.775763286},('Case3', 'A'): {'One': 0.351607026, 'Two': 0.041402396, 'Three': 0.924265706, 'Four': 0.639154727},('Case3', 'B'): {'One': 0.966538215, 'Two': 0.658236148, 'Three': 0.473447279, 'Four': 0.545974617},('Case3', 'C'): {'One': 0.036585457, 'Two': 0.279443317, 'Three': 0.407991168, 'Four': 0.101083315}}
df = pd.DataFrame(data=data)

# 转换为适配绘图的长格式
df_long = df.stack(level=0).reset_index()
df_long.columns = ['Row', 'Case', 'A', 'B', 'C']
# 进一步拆分为更通用的绘图格式
df_plot = df_long.melt(id_vars=['Row', 'Case'], var_name='Category', value_name='Value')

两种绘图方案

方案1:合并绘制(类似Excel分组柱状图)

将所有Case整合到同一视图,按行索引(One/Two/Three/Four)分组,展示不同Case的A/B/C类别数据:

# 单图分组展示
plt.figure(figsize=(12, 6))
sns.barplot(data=df_plot, x='Row', y='Value', hue='Case', palette='viridis', errorbar=None)
plt.title('所有Case的分组柱状图')
plt.tight_layout()
plt.show()

# 按A/B/C拆分子图展示
g = sns.FacetGrid(df_plot, col='Category', col_wrap=3, height=4)
g.map(sns.barplot, 'Row', 'Value', 'Case', palette='viridis', errorbar=None)
g.add_legend()
plt.tight_layout()
plt.show()

方案2:每个Case单独绘图

循环遍历每个Case,生成独立的柱状图,便于单独分析:

cases = df_plot['Case'].unique()
for case in cases:
    case_data = df_plot[df_plot['Case'] == case]
    plt.figure(figsize=(8, 5))
    sns.barplot(data=case_data, x='Row', y='Value', hue='Category', palette='coolwarm', errorbar=None)
    plt.title(f'{case} 数据柱状图')
    plt.ylabel('数值')
    plt.tight_layout()
    plt.show()

关键说明

  • stack(level=0)将一级表头(Case1/2/3)转为行索引,再通过reset_index展开,确保层级信息完整保留
  • melt转换时保留Row和Case作为标识变量,让后续绘图能精准分组
  • 使用seaborn比matplotlib原生API更易实现类似Excel的分组效果,也能快速拆分多子图

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 13:21:23