Подтвердить что ты не робот

Типовой код Matplotlib - превышает ошибку Locator.MAXTICKS без видимых причин

Когда я рисую данные по времени и времени, охватывая более двух дней, я устанавливаю datelocator на 0 и 30 минут. Основной тик на каждые полчаса, matplotlib выдает ошибку. Рассмотрим этот пример:

from datetime import datetime
import matplotlib.pyplot as plt
import matplotlib.dates as mdates

datapoints = 3600*24*2   #2 days, 1 datapoint/second
data = range(datapoints)  #anydata
timestamps = [ datetime.fromtimestamp(t) for t in range(datapoints) ]

fig = plt.figure()
ax = fig.add_subplot(1,1,1)   
ax.xaxis.set_major_locator(mdates.MinuteLocator(byminute=[0,30]))

plt.plot(timestamps,data)
plt.show()

Затем я получаю следующую ошибку:

RuntimeError: RRuleLocator, по оценкам, генерирует 2879 тиков от 1970-01-01 01: 00: 00 + 00: 00-1970-01-03 00: 59: 59 + 00: 00: превышает Locator.MAXTICKS * 2 (2000)

2879 тиков - это точно количество минут в этот промежуток времени, то есть оценка основана на 1 тике каждую минуту. Однако локатор должен давать 1 тик каждые 30 минут (2 тика в час в течение 48 часов = 96 тиков). Почему оценка и реальная ценность до сих пор находятся друг от друга?

Обходным решением будет повышение значения MAXTICKS:

locator = mdates.MinuteLocator(byminute=[0,30])
locator.MAXTICKS = 1500
ax.xaxis.set_major_locator(locator)

Это работает, и график прекрасно показывает. Однако это не нужно правильно? Почему эта ошибка возникает в первую очередь? Я использую datelocator wronly?

4b9b3361

Ответ 1

Реальная проблема заключается в том, что RRuleLocator предполагает, что базовая переменная интервала rrule-экземпляра будет обновлена, если значение minmin установлено, а интервал не передается при инициализации (по умолчанию он равен 1). Фактически, интервал полностью игнорируется в rrule (с некоторыми небольшими исключениями w.r.t., если фильтр установлен или нет), когда установлено byxxx (час/минута/секунда и т.д.)!

Вместо того, чтобы переопределять MAXTICKS, лучше всего изменить код, чтобы включить интервал в MinuteLocator равным 30. Это не изменит, как окончательное изображение рисуется в соответствии с приведенным выше (если вы не используете фильтр).

ax.xaxis.set_major_locator(mdates.MinuteLocator(byminute=[0,30], interval=30))

Предположим, что хотя это и является обходным путем, проверка оценки в файле RRuleLocator tick_values ​​может быть очищена, чтобы включить то, что установлено в переменные byxxx (хотя это может стать беспорядочным).

Ответ 2

Кажется, у вашей оси X слишком много меток для обработки программы.

Попробуйте изменить

    ax.xaxis.set_major_locator(mdates.MinuteLocator(byminute=[0,30]))

к

    ax.xaxis.set_major_locator(mdates.HourLocator(byhour=[0,1]))

Максимальное количество тиков по умолчанию - 2000, которое является locator.MAXTICKS * 2.
Работая за несколько минут, у вас было 2879 тиков. Это на 1440 минут в день в течение двух дней плюс буфер из 79 тиков.

Изменение оси x до часов дает 48 часов плюс тики буфера, которые находятся под пределом 2000 тиков по оси x.

Изменение MAXTICKS по умолчанию до 1500 может работать, но оно побеждает предполагаемую защиту.

В это время нет опции для отметки 30 минут.