有一个历元列表,pyplot
或numpy
中是否有一个参数可以构成一个直方图,其中bins
与data
列表中的月份相匹配?在此示例中,列表对应于2012年至2013年的随机日期。如果data
中的值仅对应于这几个月中的日期,我希望直方图显示从2012年2月至2013年10月的条形图
此代码制作了一个直方图,但它为bins=24
手动分隔。
import numpy as np
import matplotlib.mlab as mlab
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import random
data = [int(random.randint(1293836400, 1356994800)) for _ in range(1000)]
# convert the epoch format to matplotlib date format
mpl_data = mdates.epoch2num(data)
fig, ax = plt.subplots(1,1)
ax.hist(mpl_data, bins=24, ec='black')
ax.xaxis.set_major_locator(mdates.MonthLocator())
ax.xaxis.set_major_formatter(mdates.DateFormatter('%d.%m.%y'))
fig.autofmt_xdate()
plt.show()
答案 0 :(得分:0)
为此,您必须选择每个月初开始的时间戳。日期/时间总是比常规数字复杂得多,因此尽管此代码看起来有点麻烦,但它确实可以工作。
import numpy as np
import matplotlib.mlab as mlab
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import random
data = [int(random.randint(1293836400, 1356994800)) for _ in range(1000)]
# create your bins as timestamps marked at the beginning of each month, using datetime objects to increment
import datetime as d
mindate = d.datetime.fromtimestamp(min(data))
maxdate = d.datetime.fromtimestamp(max(data))
bindate = d.datetime(year=mindate.year, month=mindate.month, day=1)
bins = [bindate.timestamp()]
while bindate < maxdate:
if bindate.month == 12:
bindate = d.datetime(year=bindate.year + 1, month=1, day=1)
else:
bindate = d.datetime(year=bindate.year, month=bindate.month + 1, day=1)
bins.append(bindate.timestamp())
bins = mdates.epoch2num(bins)
mpl_data = mdates.epoch2num(data)
fig, ax = plt.subplots(1,1, figsize=(16, 4), facecolor='white')
ax.hist(mpl_data, bins=bins, ec='black')
ax.xaxis.set_major_locator(mdates.MonthLocator())
ax.xaxis.set_major_formatter(mdates.DateFormatter('%d.%m.%y'))
fig.autofmt_xdate()
另一种方法是使用pandas
按月份对数据进行分组,然后对它们进行计数。代码要短得多,您可以进行快速条形图绘制。要在上面重新创建绘图,将需要更多的工作,但这会让您感觉可以使用其他工具进行操作:
srs = pd.DatetimeIndex(pd.Series(data) * 1e9) # convert sec to nsec
df = pd.DataFrame({'count': np.ones(shape=len(srs))}, index=srs)
fig, ax = plt.subplots(1, 1, figsize=(16,4), facecolor='white')
df.groupby(pd.Grouper(freq='M')).count().plot.bar(ax=ax)