Matplotlib: линейная коллекция на основе даты и времени в интерактивном сюжете Юпитера - PullRequest
0 голосов
/ 12 марта 2019

Я пытаюсь построить коллекцию из десятков тысяч линейных сегментов в интерактивном графике matplotlib в блокноте Jupyter. У меня проблема в том, что

  • значения x представляют собой дату-время (datetime64 [нс], в основном метки времени POSIX)
  • LineCollection с могут быть основаны только на числах
  • при выходе из оси X графика в виде чисел, когда я масштабирую график, ось X корректно масштабируется в соответствии с масштабом. Однако значения оси X неинформативны. При форматировании оси X в информативные значения даты и времени эта информация теряется при увеличении.

Пример:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import collections  as mc
import matplotlib.dates as mdates

%matplotlib nbagg # interactive plot in jupyter notebook

x = np.array([['2018-03-19T07:01:00.000073810', '2018-03-19T07:01:00.632164618'],
       ['2018-03-19T07:01:00.000073811', '2018-03-19T07:01:00.742295898'],
       ['2018-03-19T07:01:00.218747698', '2018-03-19T07:01:00.260067814'],
      ['2018-03-19T07:01:01.218747698', '2018-03-19T07:01:02.260067814'],
      ['2018-03-19T07:01:02.218747698', '2018-03-19T07:01:02.260067814'],
      ['2018-03-19T07:01:02.218747698', '2018-03-19T07:01:02.260067814']],
      dtype='datetime64[ns]')
y = np.array([[12355.5, 12355.5],
       [12363. , 12363. ],
       [12362.5, 12362.5],
       [12355.5, 12355.5],
       [12363. , 12363. ],
       [12362.5, 12362.5]])

fig, ax = plt.subplots()
segs = np.zeros((x.shape[0], x.shape[1], 2))
segs[:, :, 1] = y
segs[:, :, 0] = mdates.date2num(x)
lc = mc.LineCollection(segs)
ax.set_xlim(segs[:,:,0].min(), segs[:,:,0].max())
ax.set_ylim(segs[:,:,1].min()-1, segs[:,:,1].max()+1)
ax.add_collection(lc)

Теперь, масштабирование работает нормально - масштаб оси X регулируется с помощью увеличения - но значения оси X не дают мне ничего полезного, то есть точное время, в которое я сейчас смотрю. Чтобы исправить это, я попытался, например, делать:

ax.xaxis.set_major_locator(mdates.SecondLocator())
#ax.xaxis.set_minor_locator(mdates.MicrosecondLocator()) # this causes the plot not to display
Fmt = mdates.DateFormatter("%S")
ax.xaxis.set_major_formatter(Fmt)

Теперь очевидно, что масштабирование не работает нормально, поскольку matplotlib не знает, как форматировать более мелкие тики. Поэтому, если я достаточно увеличу масштаб, что мне нужно сделать, у меня практически не будет отметок по оси X.

Есть ли способ решить эту проблему? Один из способов, который я мог бы придумать, - это настроить обратный вызов, который вызывается при увеличении графика, и настроить формат оси X. Но, насколько я мог найти, это невозможно.

1 Ответ

1 голос
/ 12 марта 2019

Похоже, что основная проблема в настоящее время состоит в том, чтобы получить только какие-нибудь полезные галочки и метки на вашем графике.Стандартный способ сделать это будет

loc = mdates.AutoDateLocator()
fmt = mdates.AutoDateFormatter(loc)
ax.xaxis.set_major_locator(loc)
ax.xaxis.set_major_formatter(fmt)

. Он автоматически выберет для вас полезные места для тиков и будет корректным с точностью до нескольких микросекунд;ниже этого тиканье может стать неточным из-за ограничений с плавающей запятой.

То есть, если вам нужны индивидуальные или более точные местоположения галочек, вам нужно написать свой собственный локатор и / или изменить единицы ваших данных (например, на «секунды с полуночи»).

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