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

遍历barplot容器元素时部分标签缺失(endline无N值)求助

解决Seaborn条形图中Endline标签缺失N值的问题

问题原因

你的代码中,ax.containers对应每个level分组的条形容器(共3个:low、medium、high),每个容器包含两个条形(baseline和endline)。但你通过pd.DataFrame(N['id']).to_numpy()得到的是6个独立的id值(每个survey+level组合对应一个),和容器数量不匹配,导致每个容器只能获取第一个id值,第二个条形(endline)没有对应的N数据,最终标签缺失。

修正方案

重新组织N的id数据,按level分组,让每个分组对应该level下baseline和endline的两个id计数,再和容器一一匹配:

完整修正代码

import pandas as pd
import numpy as np
import seaborn as sns

import matplotlib.pyplot as plt
from matplotlib.ticker import PercentFormatter

data = {
"id": [1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22],
"survey": ['baseline', 'endline', 'baseline', 'endline', 'baseline', 'endline', 'baseline', 'endline', 'baseline', 'endline', 'baseline', 'endline', 'baseline', 'endline', 'baseline', 'endline', 'baseline', 'endline', 'baseline', 'endline', 'baseline', 'endline', 'baseline', 'endline', 'baseline', 'endline', 'baseline', 'endline', 'baseline', 'endline', 'baseline', 'endline', 'baseline', 'endline', 'baseline', 'endline', 'baseline', 'endline', 'baseline', 'endline', 'baseline', 'endline', 'baseline', 'endline'],
"level": ['low', 'high', 'medium', 'low', 'high', 'medium', 'medium', 'high', 'low', 'low', 'medium', 'high', 'low', 'medium', 'low', 'high', 'low', 'low', 'medium', 'high', 'high', 'high', 'high', 'medium', 'low', 'low', 'medium', 'high', 'low', 'medium', 'high', 'medium', 'low', 'high', 'high', 'medium', 'medium', 'low', 'high', 'low', 'low', 'low', 'low', 'low']
}

df = pd.DataFrame(data)

N = df.groupby(['survey', 'level']).count().sort_index(ascending = True).reset_index()
N['%'] = 100 * N['id'] / N.groupby('survey')['id'].transform('sum')

sns.set_style('white')
ax = sns.barplot(data = N, x = 'survey', y = '%', ci = None,
                palette="rainbow", hue = 'level')

# 关键修正:按level分组提取对应baseline和endline的id计数
id_groups = N.groupby('level')['id'].apply(list).tolist()

labels = [
    [f'{pct:.1f}% $(N={_n})$' for pct, _n in zip(c.datavalues, ids)]
    for c, ids in zip(ax.containers, id_groups)
]

for container, label in zip(ax.containers, labels):
    ax.bar_label(container, label, fontsize = 10)

sns.despine(ax = ax, left = True)
ax.grid(True, axis = 'y')
ax.yaxis.set_major_formatter(PercentFormatter(100))
ax.set_xlabel('')
ax.set_ylabel('')
plt.tight_layout()
plt.legend(bbox_to_anchor = (1.02, 1), loc = 'upper left', borderaxespad=0)
plt.show()

核心修改说明

  • N.groupby('level')['id'].apply(list)会将每个level对应的baseline、endline计数打包成列表,比如low对应的列表是[baseline_low_count, endline_low_count],正好匹配每个容器中的两个条形。
  • 这样每个容器能获取到对应的两个N值,生成完整的百分比+N标签,解决endline标签缺失的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 04:05:15