Для этого вам нужно выбрать временные метки, с которых начинается начало каждого месяца. Даты / времена всегда намного сложнее, чем обычные числа, поэтому, хотя этот код выглядит немного громоздким, он работает.
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)