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

seaborn barplot为柱条标注多个自定义值时触发IndexError索引越界报错

报错根因

你触发IndexError: list index out of range的核心原因是hue参数的机制问题:

  • 即使设置了dodge=False不让柱条错开,seaborn的barplot只要传入hue参数,就会为hue列的每个唯一分类、每个x轴刻度都生成一个patch(柱条对象),没有数据的位置会生成高度为0的占位patch。
  • 你的示例中groups列有3个唯一值,x轴rules有3个分类,最终plots.patches总长度是9,但你提取的percentage、weight列表长度只有3,循环到i=3时就会访问列表不存在的索引,直接报错。
  • 另外原代码还有显示逻辑bug:柱内weight标注的y坐标和柱顶百分比的y坐标完全一致,即使不报错,weight值也会显示在柱条外部,达不到柱内标注的效果。
正确实现方案

遍历patch时跳过高度为0的占位柱,同时调整两个标注的y坐标位置,保证百分比在柱顶、weight值在柱内部居中显示,可直接运行的代码如下:

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

# 示例DataFrame,替换为你的实际数据即可
df = pd.DataFrame({
    "rules": ["A", "B", "C"],
    "count": [15, 5, 25],
    "percentage": ["24%", "2%", "50%"],
    "groups": [1, 2, 3],
    "weight": [10, 30, 50]
})

sns.set(rc={'figure.figsize':(18,9.5)})
ax = sns.barplot(x="rules", y="count", data=df, hue="groups", dodge=False, palette="Set2")

bar_idx = 0
for patch in ax.patches:
    bar_height = patch.get_height()
    # 跳过hue生成的高度为0的无效占位柱
    if bar_height == 0:
        continue
    x_pos = patch.get_x() + patch.get_width()/2
    # 柱顶标注百分比,y轴向上偏移0.5避免贴住柱条
    ax.annotate(
        f"{df['percentage'].iloc[bar_idx]}",
        (x_pos, bar_height + 0.5),
        ha='center', va='bottom', size=14
    )
    # 柱内部居中标注weight值
    ax.annotate(
        f"{df['weight'].iloc[bar_idx]}",
        (x_pos, bar_height/2),
        ha='center', va='center', color='white', size=15, fontweight="bold"
    )
    bar_idx += 1

ax.set_xticklabels(ax.get_xticklabels(), rotation=90, fontsize=15)
# 不需要hue图例可以打开下面这行注释
# ax.get_legend().remove()
plt.tight_layout()
plt.show()
补充说明
  • 如果不需要按groups列给柱条区分颜色,直接删掉hue=df['groups']参数即可,此时patches长度和df行数完全一致,不会生成占位patch,但仍需要调整weight标注的y坐标,否则会显示在柱外。
  • 柱顶标注的y轴偏移量(代码中bar_height + 0.5的0.5)可以根据你的count值范围灵活调整,避免标注和柱条距离过远或过近。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 13:27:19