Как использовать matplotib.dates.date2num, чтобы получить ширину баров в гистограмме? - PullRequest
0 голосов
/ 20 января 2020

Я пытаюсь создать гистограмму, для которой ось 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)

Example output plot

В случае, если неясно, я спрашиваю, является ли date2num подходящим способом получить ширину стержня для любой Форматирование по оси X. Если нет, то какой путь лучше?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...