如何调整柱状图宽度匹配次X轴指定天数及查询Pandas绘图文档
解决方案
柱状图柱宽匹配天数实现
核心逻辑
原使用pandas内置plot(kind='bar')默认基于分类轴绘制等宽柱子,无法匹配不同周的天数差异。需要改用日期作为x轴单位,手动计算每个柱子的中心位置和宽度,即可让柱子宽度和对应周的天数完全对齐。
修改后完整代码
import pandas as pd import matplotlib.pyplot as plt from matplotlib.dates import DateFormatter, DayLocator import datetime from calendar import monthrange def weekly_breakdown(year=2021, month=11): total_days = monthrange(year, month)[1] if total_days % 4 == 0: # 28 / 4 = 7 days_per_week = (7, 7, 7, 7) elif total_days % 4 == 2: # 30 / 4 = 7.5 days_per_week = (8, 7, 8, 7) elif total_days % 4 == 3: # 31 / 4 = 7.75 days_per_week = (8, 8, 8, 7) return days_per_week # 生成数据部分和原逻辑一致 df1 = pd.DataFrame( [100, 1650, 2000, 3500], index=['Week 1', 'Week 2', 'Week 3', 'Week 4'], columns=['Amount'] ) df2 = pd.DataFrame( [750, 1500, 2250, 3000], index=['Week 1', 'Week 2', 'Week 3', 'Week 4'], columns=['Amount'] ) days = pd.date_range(start="2021-11-01", end="2021-11-30").to_pydatetime().tolist() daily_df = pd.DataFrame( list(range(100, 3100, 100)), index=days, columns=['Cumulative'] ) # 计算每周的起始日期、宽度、中心位置 year, month = 2021, 11 dpw = weekly_breakdown(year, month) start_date = datetime.datetime(year, month, 1) week_centers = [] week_widths = [] current = start_date for d in dpw: # 柱子中心位置 = 起始日 + 天数/2 week_centers.append(current + datetime.timedelta(days=d/2)) week_widths.append(d) current += datetime.timedelta(days=d) # 绘图部分 fig, ax1 = plt.subplots(figsize=(8, 6), nrows=1, ncols=1) ax2 = ax1.twiny() # 绘制不等宽柱状图,同周两个柱子重叠展示(如果需要并列展示,只需调整x位置和宽度拆分即可) ax1.bar(week_centers, df1['Amount'], width=week_widths, color='red') ax1.bar(week_centers, df2['Amount'], width=week_widths, color='white', edgecolor='black', alpha=0.5) # 绘制折线 daily_df['Cumulative'].plot(kind='line', ax=ax2, marker='o') # 轴配置 ax1.set_xticks(week_centers) ax1.set_xticklabels(df1.index) ax1.tick_params(axis='x', rotation=0, length=0, pad=30) ax1.set_ylabel('Dollars') # 两个x轴范围完全对齐 ax1.set_xlim([start_date, start_date + datetime.timedelta(days=sum(dpw))]) ax2.xaxis.tick_bottom() ax2.tick_params(axis='x', which='major', length=3) ax2.tick_params(axis='x', which='minor', length=3) ax2.set_xlim([daily_df.index[0], daily_df.index[-1]]) ax2.xaxis.set_major_locator(DayLocator(interval=1)) ax2.xaxis.set_major_formatter(DateFormatter("%d")) plt.show()
附加问题解答
df.plot()是Pandas封装的上层绘图接口,不属于Matplotlib的功能范畴,因此在Matplotlib文档中无法搜索到。你可以直接搜索「pandas.DataFrame.plot 官方文档」获取所有参数说明,其中包含kind参数所有可选值的用法、配置项说明。
内容的提问来源于stack exchange,提问作者Simon1
相关产品推荐
相关产品推荐

