使用每月数据控制matplotlib中条形图的宽度

24 投票
2 回答
75422 浏览
提问于 2025-04-15 11:43

当我用柱状图展示每个月的数据时,柱子的宽度非常细。如果我把X轴的小刻度设置为DayLocator(),我能看到柱子的宽度调整为1天,但我希望它们能填满整个月。

我尝试把小刻度定位器设置为MonthLocator(),但没有效果。

[编辑]

也许举个例子会更清楚,这里有一个ipython -pylab的例子来说明我的意思:

x = [datetime.datetime(2008, 1, 1, 0, 0),
    datetime.datetime(2008, 2, 1, 0, 0),
    datetime.datetime(2008, 3, 1, 0, 0),
    datetime.datetime(2008, 4, 1, 0, 0),
    datetime.datetime(2008, 5, 1, 0, 0),
    datetime.datetime(2008, 6, 1, 0, 0),
    datetime.datetime(2008, 7, 1, 0, 0),
    datetime.datetime(2008, 8, 1, 0, 0),
    datetime.datetime(2008, 9, 1, 0, 0),
    datetime.datetime(2008, 10, 1, 0, 0),
    datetime.datetime(2008, 11, 1, 0, 0),
    datetime.datetime(2008, 12, 1, 0, 0)]

y = cos(numpy.arange(12) * 2)

bar(x, y)

这个例子生成了12个宽度为2像素的柱子,我希望它们更宽,并且能够从一个月延伸到下一个月。

2 个回答

0

更新后的matplotlib版本(比如3.7.0)可以直接处理日期和时间差,所以你只需要计算它们之间的差值(可以用np.diff()这个函数),就能得到一个宽度的列表。

import datetime
import numpy as np
import matplotlib.pyplot as plt

x = [datetime.datetime(2008, i, 1) for i in range(1, 13)]
y = np.cos(np.arange(12) * 2)

# plot a bar chart with timedelta x-axis
plt.bar(x, y, width=[*np.diff(x), datetime.timedelta(31)]);

另一种方法是直接画一个柱状图,不用太担心x轴的设置,之后再把日期数据作为刻度标签加上去。

plt.bar(range(len(x)), y)
plt.xticks(range(0, len(x), 2), [d.strftime('%Y-%m') for d in x[::2]]);

结果

61

只需要使用 width 这个参数就可以了:

bar(x, y, width=30)

另外,由于不同的月份天数不同,为了让显示效果更好,你可以使用一个序列:

bar(x, y, width=[(x[j+1]-x[j]).days for j in range(len(x)-1)] + [30])

撰写回答