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

如何用Matplotlib绘制含Yes/No分组的年龄频率直方图?

绘制Resigned分组(Yes/No)的年龄频率直方图问题解决

问题背景

已完成数据值计数,目标是用Matplotlib绘制分组直方图:X轴为年龄,Y轴为频率,"Yes"和"No"组用不同颜色。但现有代码执行后得到异常直方图。

数据与现有代码

数据预览

Resigned  Age
No        18      4
          19      3
          20      5
          21      7
          22     11
                 ..
Yes       52      3
          53      2
          55      3
          56      3
          58      5
Length: 82, dtype: int64

完整计数数据(字典形式)

counts_dict = {('No', 18): 4, ('No', 19): 3, ('No', 20): 5, ('No', 21): 7, ('No', 22): 11, ('No', 23): 10, ('No', 24): 19, ('No', 25): 20, ('No', 26): 27, ('No', 27): 45, ('No', 28): 34, ('No', 29): 50, ('No', 30): 51, ('No', 31): 51, ('No', 32): 50, ('No', 33): 46, ('No', 34): 68, ('No', 35): 68, ('No', 36): 63, ('No', 37): 44, ('No', 38): 56, ('No', 39): 36, ('No', 40): 52, ('No', 41): 34, ('No', 42): 44, ('No', 43): 30, ('No', 44): 27, ('No', 45): 39, ('No', 46): 29, ('No', 47): 21, ('No', 48): 17, ('No', 49): 22, ('No', 50): 25, ('No', 51): 17, ('No', 52): 15, ('No', 53): 17, ('No', 54): 18, ('No', 55): 19, ('No', 56): 11, ('No', 57): 4, ('No', 58): 9, ('No', 59): 10, ('No', 60): 5, ('Yes', 18): 4, ('Yes', 19): 6, ('Yes', 20): 6, ('Yes', 21): 6, ('Yes', 22): 5, ('Yes', 23): 4, ('Yes', 24): 7, ('Yes', 25): 6, ('Yes', 26): 12, ('Yes', 27): 3, ('Yes', 28): 14, ('Yes', 29): 18, ('Yes', 30): 9, ('Yes', 31): 18, ('Yes', 32): 11, ('Yes', 33): 12, ('Yes', 34): 9, ('Yes', 35): 10, ('Yes', 36): 6, ('Yes', 37): 6, ('Yes', 38): 2, ('Yes', 39): 6, ('Yes', 40): 5, ('Yes', 41): 6, ('Yes', 42): 2, ('Yes', 43): 2, ('Yes', 44): 6, ('Yes', 45): 2, ('Yes', 46): 4, ('Yes', 47): 3, ('Yes', 48): 2, ('Yes', 49): 2, ('Yes', 50): 5, ('Yes', 51): 2, ('Yes', 52): 3, ('Yes', 53): 2, ('Yes', 55): 3, ('Yes', 56): 3, ('Yes', 58): 5}

现有代码

agereg_counts.plot(kind='hist', bins=30) # ratio data
plt.title('Fig. 1 Revolution Consulting - Age Info')
plt.xlabel('Age')

问题原因

现有代码直接对计数值调用直方图绘制,会把计数本身作为样本统计分布,而非以年龄为X轴、计数为Y轴展示分组频率,因此结果不符合预期。

解决方案

根据需求,推荐三种实现方式,按需选择:

1. 并列柱状图(展示每个年龄的分组频率)

适合离散年龄的精确对比:

import pandas as pd
import matplotlib.pyplot as plt

# 转换数据为宽格式DataFrame
df = pd.Series(counts_dict).unstack(level=0, fill_value=0)
ages = df.index
x_pos = range(len(ages))
bar_width = 0.35

# 绘制并列柱子
fig, ax = plt.subplots(figsize=(12,6))
ax.bar([x - bar_width/2 for x in x_pos], df['No'], bar_width, label='No', color='#1f77b4')
ax.bar([x + bar_width/2 for x in x_pos], df['Yes'], bar_width, label='Yes', color='#ff7f0e')

# 设置图表属性
ax.set_xlabel('Age')
ax.set_ylabel('Frequency')
ax.set_title('Fig. 1 Revolution Consulting - Age Info')
ax.set_xticks(x_pos)
ax.set_xticklabels(ages)
ax.legend(title='Resigned')

plt.tight_layout()
plt.show()

2. 堆叠柱状图(展示每个年龄的总频率及分组占比)

适合观察各年龄的整体分布与分组构成:

import pandas as pd
import matplotlib.pyplot as plt

df = pd.Series(counts_dict).unstack(level=0, fill_value=0)
df.plot(kind='bar', stacked=True, color=['#1f77b4', '#ff7f0e'], figsize=(12,6))

plt.xlabel('Age')
plt.ylabel('Frequency')
plt.title('Fig. 1 Revolution Consulting - Age Info')
plt.legend(title='Resigned')
plt.tight_layout()
plt.show()

3. 分组直方图(按年龄区间统计频率)

如果需要将年龄划分为连续区间展示分布:

import pandas as pd
import matplotlib.pyplot as plt

# 将计数数据转换为原始长格式
long_data = []
for (resigned, age), cnt in counts_dict.items():
    long_data.extend([(resigned, age)] * cnt)
long_df = pd.DataFrame(long_data, columns=['Resigned', 'Age'])

# 绘制分组直方图
plt.figure(figsize=(10,6))
plt.hist(
    [long_df[long_df['Resigned']=='No']['Age'], long_df[long_df['Resigned']=='Yes']['Age']],
    bins=10, # 可调整区间数量
    label=['No', 'Yes'],
    color=['#1f77b4', '#ff7f0e'],
    alpha=0.7 # 透明度,方便查看重叠部分
)

plt.xlabel('Age')
plt.ylabel('Frequency')
plt.title('Fig. 1 Revolution Consulting - Age Info')
plt.legend(title='Resigned')
plt.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 04:05:54