如何在pandas柱状图中实现类似直方图的分箱调整
解决按6年间隔统计参议员任期并绘制柱状图的问题
我明白你的困扰——原来按每年统计的柱状图太密集,可读性差,而直接给bar图加bins参数会报错,因为bar绘图方法根本没有这个参数(bins是直方图hist专属的)。咱们需要换个思路:先对任期数据按6年间隔分组统计,再用统计结果绘制柱状图。
解决方案代码
先修改你的统计逻辑,把单一年份的统计改成6年区间的分组统计:
import pandas as pd import numpy as np import matplotlib.pyplot as plt def tenure_count(frame, party, bin_size=6): # 筛选当前党派的任期数据 party_tenures = frame[frame.party == party]['tenure'] # 生成覆盖所有任期的区间边界(从0开始,步长为bin_size) max_tenure = frame['tenure'].max() bins = range(0, max_tenure + bin_size, bin_size) # 对任期进行分组,并统计每组的数量,按区间排序 interval_counts = pd.cut(party_tenures, bins=bins, right=False).value_counts().sort_index() # 确保所有区间都被包含(即使某个区间没有数据也要填充0) all_intervals = pd.IntervalIndex.from_tuples([(left, left+bin_size) for left in bins[:-1]]) interval_counts = interval_counts.reindex(all_intervals, fill_value=0) # 把区间索引改成更友好的文本标签(比如"0-6 years") interval_counts.index = interval_counts.index.map(lambda x: f"{x.left}-{x.right} years") return interval_counts # 加载并预处理数据 df = pd.read_csv("congress_tenure.csv", header=0) df = df[['tenure', 'party']].sort_values('tenure') parties = ['Democrat', 'Republican', 'Democratic-Republican', 'Whig', 'Federalist'] # 生成各党派的6年区间统计结果 counts = pd.DataFrame({party: tenure_count(df, party) for party in parties}) # 绘制柱状图 counts.plot(kind='bar', figsize=(12, 6)) plt.title('Senator Tenure Frequency by Party (6-Year Intervals)') plt.xlabel('Tenure Interval') plt.ylabel('Number of Senators') plt.legend(title='Political Party') plt.tight_layout() # 自动调整布局避免标签被截断 plt.show()
关键改动说明
- 分组统计逻辑:用
pd.cut把任期划分成[0,6)、[6,12)...这样的6年区间,然后统计每个区间内的参议员数量,替代原来按单一年份的value_counts。 - 补全空区间:用
reindex确保所有6年区间都出现在结果中,避免因为某个区间没有数据而缺失柱子。 - 友好索引标签:把区间对象转换成易读的文本标签,让图表的横轴更直观。
- 移除错误的
bins参数:因为bar图是基于已经统计好的离散值绘图,不需要bins——bins是直方图用来自动划分连续数据的参数,和柱状图逻辑不同。
这样生成的柱状图每个柱子代表6年的任期区间,数量大幅减少,可读性会提升很多,同时也能清晰展示不同党派的任期分布差异。
内容的提问来源于stack exchange,提问作者embradley
相关产品推荐
相关产品推荐

