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

如何调整柱状图宽度匹配次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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 11:15:11