Я пытаюсь создать гистограмму, для которой ось X масштабируется по дате / времени. Я могу создать график, но я не уверен, как проверить точность графика, потому что я не совсем понимаю, как работает date2num
через matplotlib.dates
. Согласно документам возвращает следующее:
Количество дней (дробная часть представляет часы, минуты, секунды, мс) с 0001-01-01 00 : 00: 00 UT C, плюс один.
Итак, следует ли заметить изменение в графике, если отметки оси x (младшие или основные) отформатированы так, чтобы показывать месяцы ( или дни или годы) при использовании date2num
? У меня есть небольшая демонстрация ниже, которая может помочь понять это.
В приведенном ниже примере мне нужно date2num
, чтобы вычислить ширину каждого бара; в противном случае мне нужно указать единицу, используя объект datetime.timedelta
. В моем реальном случае использования datetime соответствуют кластерам событий; Я хотел бы показать значения y как число событий в кластере, для которого ширина столбца простирается вдоль x от даты и времени первого и последнего событий в указанном кластере.
Рассмотрим следующее пример:
import numpy as np
import datetime
import matplotlib.pyplot as plt
from matplotlib.dates import date2num, YearLocator, MonthLocator, DayLocator, WeekdayLocator, HourLocator, MinuteLocator, SecondLocator, DateFormatter
lbound = datetime.datetime(2000, 12, 25, 0, 0, 0)
dts = []
for i in range(10):
new_dt = lbound + i * datetime.timedelta(days=1)
dts.append(new_dt)
edges = np.array(dts)
# print("\n .. {} EDGES:\n{}\n".format(edges.size, edges))
.. 10 EDGES:
[datetime.datetime(2000, 12, 25, 0, 0)
datetime.datetime(2000, 12, 26, 0, 0)
datetime.datetime(2000, 12, 27, 0, 0)
datetime.datetime(2000, 12, 28, 0, 0)
datetime.datetime(2000, 12, 29, 0, 0)
datetime.datetime(2000, 12, 30, 0, 0)
datetime.datetime(2000, 12, 31, 0, 0) datetime.datetime(2001, 1, 1, 0, 0)
datetime.datetime(2001, 1, 2, 0, 0) datetime.datetime(2001, 1, 3, 0, 0)]
Учитывая 10
datetime, предположим, что я принимаю середину каждых двух последовательных datetime за координату x, а ширину каждого бара - за время между этими последовательными datetime , (Y-координата (высота стержня) в этом примере произвольна.) Это можно сделать с помощью date2num
через matplotlib.dates
:
xs, ws = [], []
for lower_edge, upper_edge in zip(edges[1:], edges[:-1]):
_lw = date2num(lower_edge)
_uw = date2num(upper_edge)
w = _uw - _lw
xs.append(_lw + w/2)
ws.append(w)
xs = np.array(xs)
ws = np.array(ws)
ys = np.sin(xs)
График можно получить с помощью:
fmt = "%Y-%m-%d"
fig, ax = plt.subplots()
ax.bar(xs, ys, width=ws, color='r')
ax.xaxis.set_major_locator(YearLocator())
ax.xaxis.set_minor_locator(MonthLocator())
ax.xaxis.set_major_formatter(DateFormatter(fmt))
ax.tick_params(axis='x', rotation=15)
plt.show()
plt.close(fig)
В случае, если неясно, я спрашиваю, является ли date2num
подходящим способом получить ширину стержня для любой Форматирование по оси X. Если нет, то какой путь лучше?