如何绘制以国家为分箱的直方图?求Python实现指导
澄清直方图 vs 条形图的核心差异,以及解决你的需求
首先得明确一个关键概念:你想要的图本质上是条形图,而不是直方图——这也是你用kind='bar'能正常运行的原因。咱们先理清楚两者的区别:
- 直方图:用于展示数值型数据的分布,x轴是数值的区间(分箱),y轴是落在该区间的样本数量。比如你用
hist时,它把TOTAL的值分成了若干区间,统计每个区间有多少个国家,这是直方图的正确用法,但完全不符合你的需求。 - 条形图:用于展示类别与对应数值的关系,x轴是类别(比如国家),y轴是该类别的数值(比如总数),这正是你想要的效果。
不过如果你只是喜欢直方图那种紧凑的柱子样式,我们可以用matplotlib手动调整条形图的宽度来模拟。下面是具体的解决步骤:
步骤1:数据预处理(你的现有代码可以保留)
per_country = df.groupby(['COUNTRY'])[['TOTAL']].sum() per_country = per_country.sort_values('TOTAL')
步骤2:绘制符合你需求的图(模拟直方图样式的条形图)
import matplotlib.pyplot as plt # 设置画布大小,避免x轴标签重叠 plt.figure(figsize=(12, 6)) # 绘制宽度较宽的条形图,接近直方图的紧凑感 plt.bar(per_country.index, per_country['TOTAL'], width=0.9) # 设置轴标签和标题 plt.xlabel('Country') plt.ylabel('Total') plt.title('Total Number by Country') # 旋转x轴标签,避免过长的国家名重叠 plt.xticks(rotation=45, ha='right') # 自动调整布局,防止标签被截断 plt.tight_layout() # 显示图形 plt.show()
为什么你的直方图代码不符合预期?
当你调用medals_per_country['TOTAL'].plot(kind='hist')时,pandas会:
- 把
TOTAL列的数值分成若干连续区间(分箱) - 统计每个区间内有多少个国家(样本数)
- 用y轴展示这个统计数,x轴展示区间范围
这完全不是你想要的“每个国家对应总数”的逻辑,所以才会出现和预期不符的结果。
总结一下:如果要展示类别(国家)对应的数值(总数),条形图是正确的选择;如果喜欢直方图的视觉样式,只需要调整条形图的宽度即可达到类似效果。
内容的提问来源于stack exchange,提问作者MatthewS




