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

如何在Seaborn分组柱状图上方显示自定义百分比数值?

给Seaborn柱状图添加百分比标签

数据准备

数据存储在如下字典中:

{'Country Name': {0: 'United States',
  1: 'United States',
  2: 'United States',
  3: 'United States',
  4: 'Russian Federation',
  5: 'Russian Federation',
  6: 'Russian Federation',
  7: 'Russian Federation',
  8: 'Japan',
  9: 'Japan',
  10: 'Japan',
  11: 'Japan',
  12: 'Germany',
  13: 'Germany',
  14: 'Germany',
  15: 'Germany',
  16: 'France',
  17: 'France',
  18: 'France',
  19: 'France'},
 'Indicator Name': {0: 'Population, total',
  1: 'Population, ages 0-14, total',
  2: 'Population, ages 15-64, total',
  3: 'Population, ages 65+, total',
  4: 'Population, total',
  5: 'Population, ages 0-14, total',
  6: 'Population, ages 15-64, total',
  7: 'Population, ages 65+, total',
  8: 'Population, total',
  9: 'Population, ages 0-14, total',
  10: 'Population, ages 15-64, total',
  11: 'Population, ages 65+, total',
  12: 'Population, total',
  13: 'Population, ages 0-14, total',
  14: 'Population, ages 15-64, total',
  15: 'Population, ages 65+, total',
  16: 'Population, total',
  17: 'Population, ages 0-14, total',
  18: 'Population, ages 15-64, total',
  19: 'Population, ages 65+, total'},
 'Valeur': {0: 320896618.0,
  1: 61653419.0,
  2: 212262832.0,
  3: 46980367.0,
  4: 144096870.0,
  5: 24255306.0,
  6: 100404879.0,
  7: 19436685.0,
  8: 127141000.0,
  9: 16517168.0,
  10: 77547638.0,
  11: 33076194.0,
  12: 81686611.0,
  13: 10716271.0,
  14: 53720119.0,
  15: 17250221.0,
  16: 66624068.0,
  17: 12168975.0,
  18: 41837530.0,
  19: 12617563.0}}

现有绘图代码

ax = plt.figure(figsize=(10,5))
ax = sns.barplot(data = Graph1values, x = 'Country Name', y = 'Valeur', hue = 'Indicator Name',palette="dark")
ax = plt.xlabel('')
ax = plt.ylabel('Nombre de personnes', size = 15)
ax = plt.title('Etude de la répartition de la population', size = 20)
    
ax = plt.show()

当前柱状图呈现每个国家对应4个并列的人口统计柱子,需要给每个柱子顶部添加指定的百分比标签。

需求:添加的百分比数值

x = ['100%', '19%', '66%', '15%', '100%', '17%', '70%', '13%', '100%', '13%', '61%', '26%', '100%',
 '13%', '66%', '21%', '100%', '18%', '63%', '19%']

解决方案

原代码的核心问题是ax的赋值错误:ax = plt.figure()会把figure对象赋值给ax,后续sns.barplot返回的axes对象覆盖它,导致无法正确获取柱子容器。修正后完整代码如下:

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

# 将字典转换为DataFrame(如果尚未转换)
Graph1values = pd.DataFrame(your_data_dict)

# 正确初始化画布和坐标轴
fig, ax = plt.subplots(figsize=(10,5))
sns.barplot(data=Graph1values, x='Country Name', y='Valeur', hue='Indicator Name', palette="dark", ax=ax)

# 设置图表标签与标题
ax.set_xlabel('')
ax.set_ylabel('Nombre de personnes', size=15)
ax.set_title('Etude de la répartition de la population', size=20)

# 准备要添加的百分比标签
x = ['100%', '19%', '66%', '15%', '100%', '17%', '70%', '13%', '100%', '13%', '61%', '26%', '100%',
 '13%', '66%', '21%', '100%', '18%', '63%', '19%']

# 遍历所有柱子容器,添加标签
label_idx = 0
for container in ax.containers:
    for bar in container:
        height = bar.get_height()
        # 在柱子顶部居中位置添加标签,偏移3像素避免遮挡
        ax.annotate(x[label_idx],
                    xy=(bar.get_x() + bar.get_width() / 2, height),
                    xytext=(0, 3),
                    textcoords="offset points",
                    ha='center', va='bottom')
        label_idx += 1

plt.tight_layout()
plt.show()

关键说明

  1. 确保数据为DataFrame格式,Seaborn的barplot需要结构化数据输入
  2. 通过ax.containers获取所有分组的柱子容器,逐个遍历每个柱子
  3. 使用ax.annotate()精准控制标签的位置,设置居中对齐和微小偏移提升可读性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 09:37:22