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

如何用Python实现柱状图内嵌套堆叠柱状图?

问题

我已经绘制出展示数据集中各字母(X轴)占比(Y轴)的柱状图,现在需要在每个柱子内部嵌入堆叠柱状图,以此展示每个字母对应的female、male、neutral、other、missing的占比(每类字母内部占比总和为100%)。以下是可复现代码及堆叠数据子集:

data = {
    'L': 0.10128343899798979,
    'A': 0.04587392402453482,
    'G': 0.05204199096266515,
    'V': 0.08343212549181313,
    'E': 0.07848392694534645,
    'S': 0.03242100922632854,
    'I': 0.05353675927357696,
    'K': 0.07614727763173719,
    'R': 0.0878305241997835,
    'D': 0.05932683882274109,
    'T': 0.06166348813635036,
    'P': 0.033915777537240344,
    'N': 0.04120062539731629,
    'Q': 0.03858907616445887,
    'F': 0.033073896534542895,
    'Y': 0.04503204302183736,
    'M': 0.018126213425424805,
    'H': 0.04008384447537069,
    'C': 0.0014947683109118087,
    'W': 0.016442451420029897
}

import matplotlib.pyplot as plt
plt.bar(range(len(data)), list(data.values()), align='center')
plt.xticks(range(len(data)), list(data.keys()))

# 堆叠柱状图数据子集
# index,female,male,neutral,other,missing
# L,0.40816326530612246,0.30612244897959184,0.02040816326530612,0.0,0.2653061224489796
# A,0.34615384615384615,0.34615384615384615,0.0,0.0,0.3076923076923077
# G,0.2962962962962963,0.1111111111111111,0.037037037037037035,0.0,0.5555555555555556
# V,0.20833333333333334,0.5625,0.020833333333333332,0.0,0.20833333333333334
# E,0.5,0.225,0.025,0.0,0.25
解决方案

核心思路是用字母的总占比乘以对应分类的内部占比,得到每个分类在总柱子中的实际高度,再通过堆叠柱状图的方式逐层绘制。完整实现代码如下:

import matplotlib.pyplot as plt

# 总占比数据
data = {
    'L': 0.10128343899798979,
    'A': 0.04587392402453482,
    'G': 0.05204199096266515,
    'V': 0.08343212549181313,
    'E': 0.07848392694534645,
    'S': 0.03242100922632854,
    'I': 0.05353675927357696,
    'K': 0.07614727763173719,
    'R': 0.0878305241997835,
    'D': 0.05932683882274109,
    'T': 0.06166348813635036,
    'P': 0.033915777537240344,
    'N': 0.04120062539731629,
    'Q': 0.03858907616445887,
    'F': 0.033073896534542895,
    'Y': 0.04503204302183736,
    'M': 0.018126213425424805,
    'H': 0.04008384447537069,
    'C': 0.0014947683109118087,
    'W': 0.016442451420029897
}

# 堆叠占比数据(示例中补充了未给出的字母默认值,实际需替换为真实数据)
stack_data = {
    'L': {'female': 0.40816326530612246, 'male': 0.30612244897959184, 'neutral': 0.02040816326530612, 'other': 0.0, 'missing': 0.2653061224489796},
    'A': {'female': 0.34615384615384615, 'male': 0.34615384615384615, 'neutral': 0.0, 'other': 0.0, 'missing': 0.3076923076923077},
    'G': {'female': 0.2962962962962963, 'male': 0.1111111111111111, 'neutral': 0.037037037037037035, 'other': 0.0, 'missing': 0.5555555555555556},
    'V': {'female': 0.20833333333333334, 'male': 0.5625, 'neutral': 0.020833333333333332, 'other': 0.0, 'missing': 0.20833333333333334},
    'E': {'female': 0.5, 'male': 0.225, 'neutral': 0.025, 'other': 0.0, 'missing': 0.25},
    'S': {'female': 0.0, 'male': 0.0, 'neutral': 0.0, 'other': 0.0, 'missing': 1.0},
    'I': {'female': 0.0, 'male': 0.0, 'neutral': 0.0, 'other': 0.0, 'missing': 1.0},
    'K': {'female': 0.0, 'male': 0.0, 'neutral': 0.0, 'other': 0.0, 'missing': 1.0},
    'R': {'female': 0.0, 'male': 0.0, 'neutral': 0.0, 'other': 0.0, 'missing': 1.0},
    'D': {'female': 0.0, 'male': 0.0, 'neutral': 0.0, 'other': 0.0, 'missing': 1.0},
    'T': {'female': 0.0, 'male': 0.0, 'neutral': 0.0, 'other': 0.0, 'missing': 1.0},
    'P': {'female': 0.0, 'male': 0.0, 'neutral': 0.0, 'other': 0.0, 'missing': 1.0},
    'N': {'female': 0.0, 'male': 0.0, 'neutral': 0.0, 'other': 0.0, 'missing': 1.0},
    'Q': {'female': 0.0, 'male': 0.0, 'neutral': 0.0, 'other': 0.0, 'missing': 1.0},
    'F': {'female': 0.0, 'male': 0.0, 'neutral': 0.0, 'other': 0.0, 'missing': 1.0},
    'Y': {'female': 0.0, 'male': 0.0, 'neutral': 0.0, 'other': 0.0, 'missing': 1.0},
    'M': {'female': 0.0, 'male': 0.0, 'neutral': 0.0, 'other': 0.0, 'missing': 1.0},
    'H': {'female': 0.0, 'male': 0.0, 'neutral': 0.0, 'other': 0.0, 'missing': 1.0},
    'C': {'female': 0.0, 'male': 0.0, 'neutral': 0.0, 'other': 0.0, 'missing': 1.0},
    'W': {'female': 0.0, 'male': 0.0, 'neutral': 0.0, 'other': 0.0, 'missing': 1.0}
}

# 定义分类顺序和对应颜色
categories = ['female', 'male', 'neutral', 'other', 'missing']
colors = ['#FF9AA2', '#FFB7B2', '#FFDAC1', '#E2F0CB', '#B5EAD7']

# 获取字母列表和X轴索引
letters = list(data.keys())
x_indices = range(len(letters))

# 初始化堆叠底部位置
bottom = [0] * len(letters)

# 逐个绘制分类的堆叠部分
for cat, color in zip(categories, colors):
    # 计算当前分类的实际高度:总占比 × 内部占比
    heights = [data[letter] * stack_data[letter][cat] for letter in letters]
    # 绘制堆叠柱
    plt.bar(x_indices, heights, bottom=bottom, color=color, label=cat)
    # 更新底部位置,为下一层堆叠做准备
    bottom = [b + h for b, h in zip(bottom, heights)]

# 设置X轴刻度和标签
plt.xticks(x_indices, letters)
# 添加图例(放置在图表外侧避免遮挡)
plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left')
# 添加轴标签
plt.xlabel('字母')
plt.ylabel('总占比')
# 调整布局,防止图例被截断
plt.tight_layout()

plt.show()

关键说明

  • 数据匹配:将堆叠数据整理为嵌套字典,确保每个字母的分类占比可以快速查找;如果有完整的CSV格式数据,也可以用pandas读取后处理,效率更高。
  • 堆叠逻辑:通过bottom参数控制每一层堆叠的起始高度,最终每层高度之和等于原柱子的总高度。
  • 样式优化:给不同分类分配差异化颜色,添加清晰的图例和轴标签,提升图表可读性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 21:45:38