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

Pandas绘图:在X轴展示多层索引标签并添加条形值标签

解决方案

核心修改点

针对你的需求,主要做了两处关键调整:实现X轴双标签(forecast + year)展示、给条形添加顶部观测值标签,同时优化了子图布局样式。

1. 规整多层索引结构

先确保你的DataFrame以forecast为第一层索引,year为第二层索引,这样每个子图对应一个forecast分组:

df_par_trans = df.set_index(['forecast', 'year'])

2. 重写绘图函数实现双X轴标签

在绘图函数中替换原X轴刻度逻辑,用文本标注实现双层标签:

  • 清空默认X轴刻度,在每个条形下方居中位置添加forecast主标签
  • 在主标签下方添加year次级标签(灰色小字体)
  • 移除原X轴标题,改用子图标题展示当前forecast值

3. 添加条形顶部的观测值标签

遍历每个条形,在其顶部居中位置添加most important observation列的内容,通过Y轴偏移量避免标签与条形重叠。

4. 优化布局与样式

  • 统一隐藏刻度线,保持图表简洁
  • 增加底部边距,避免次级X轴标签被截断
  • 共享Y轴保证子图数据的可比性

完整代码

import pandas as pd
import matplotlib.pyplot as plt

# 构造示例数据
data = {
    'year': [2020, 2050, 2099, 2020, 2050, 2099],
    'forecast': ['PV6SM', 'PV6SM', 'PV6SM', 'PV3S', 'PV3S', 'PV3S'],
    'most important observation': ['Harkins', 'Harkins', 'Harkins', 'PV3S', 'PV3S', 'PV3S'],
    'percent increase when left out': [17.371021, 10.569719, 12.343476, 34.095863, 32.565513, 26.110555]
}
df = pd.DataFrame(data)
df_par_trans = df.set_index(['forecast', 'year'])

def plot_function(forecast, ax):
    sub_df = df_par_trans.xs(forecast)
    # 绘制条形图
    bars = sub_df['percent increase when left out'].plot(kind='bar', ax=ax, legend=False)
    
    # 设置子图标题为当前forecast
    ax.set_title(forecast, weight='bold')
    
    # 获取X轴位置和对应的year值
    x_ticks = ax.get_xticks()
    years = sub_df.index.tolist()
    
    # 清空原X轴标签和标题
    ax.set_xticklabels([])
    ax.set_xlabel('')
    
    # 添加双X轴标签:forecast在上,year在下
    y_bottom = ax.get_ylim()[0]
    y_range = ax.get_ylim()[1] - y_bottom
    for x, year in zip(x_ticks, years):
        # 主标签:forecast
        ax.text(x, y_bottom - y_range*0.05, forecast, ha='center', fontsize=10)
        # 次级标签:year(灰色小字体)
        ax.text(x, y_bottom - y_range*0.1, str(year), ha='center', fontsize=8, color='#666666')
    
    # 添加条形上方的观测值标签
    for bar, obs in zip(bars.patches, sub_df['most important observation']):
        height = bar.get_height()
        ax.text(bar.get_x() + bar.get_width()/2., height + y_range*0.01,
                obs, ha='center', va='bottom', fontsize=9)
    
    return bars

# 创建子图
n_subplots = len(df_par_trans.index.levels[0])
fig, axes = plt.subplots(nrows=1, ncols=n_subplots, sharey=True, figsize=(14, 8))  

# 映射forecast到对应轴并绘图
for forecast, ax in zip(df_par_trans.index.levels[0], axes):
    plot_function(forecast, ax)

# 设置Y轴标签
axes[0].set_ylabel('Percent Increase When Left Out', fontsize=11)

# 隐藏所有刻度线
for ax in axes:
    ax.tick_params(axis='both', which='both', length=0)

# 调整布局,避免标签被截断
fig.subplots_adjust(wspace=0.3, bottom=0.2)

plt.show()

效果说明

  • 每个子图对应一个forecast分组,X轴每个位置显示forecast主标签,下方展示对应的year次级标签
  • 每个条形顶部显示most important observation列的内容
  • 共享Y轴保证不同子图数据的可比性,整体布局简洁美观

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 18:05:33