график ошибок в зависимости от даты и времени не работает

Построение полосы ошибок не всегда работает, когда ось x является datetime:

z = pd.DataFrame({'timestamp': {0: pd.Timestamp('2018-06-16 04:33:27'),
  1: pd.Timestamp('2018-06-16 18:07:40')},
 'average': {0: 1.4158309812874796, 1: 1.4293226152856995},
 'stdev': {0: 0.5721450460404708, 1: 0.5771658975429514}})

Теперь z

            timestamp   average     stdev
0 2018-06-16 04:33:27  1.415831  0.572145
1 2018-06-16 18:07:40  1.429323  0.577166

plt.plot(z.timestamp, z.average) работает как положено, но plt.errorbar(z.timestamp, z.average, yerr=z.stdev) выдает

<ErrorbarContainer object of 3 artists>
Error in callback <function install_repl_displayhook.<locals>.post_execute at 0x7fe251344840> (for post_execute):


Truncated Traceback (Use C-c C-x to view full TB):
~/.virtualenvs/algorisk/local/lib64/python3.6/site-packages/matplotlib/dates.py in viewlim_to_dt(self)
   1024                              'often happens if you pass a non-datetime '
   1025                              'value to an axis that has datetime units'
-> 1026                              .format(vmin))
   1027         return num2date(vmin, self.tz), num2date(vmax, self.tz)
   1028 

ValueError: view limit minimum -7.64586229992263e+16 is less than 1 and is an invalid Matplotlib date value. This often happens if you pass a non-datetime value to an axis that has datetime units

Что я делаю не так?

PS. Другие значения, кажется, работают. Например.,

plt.errorbar(np.array([datetime.datetime(2018,7,30,12),
            datetime.datetime(2018,7,30,15)]).astype("datetime64[h]"),
         np.array([2,3]),
         yerr=np.array([1,2]))

работает как положено.


person sds    schedule 30.07.2018    source источник


Ответы (1)


Изначально matplotlib может отображать массивы numpy. Вместо предоставления pandas Series функции построения графика вы, вероятно, захотите предоставить базовые массивы numpy, полученные через .values.

import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame({'timestamp': {0: pd.Timestamp('2018-06-16 04:33:27'),
                                1: pd.Timestamp('2018-06-16 18:07:40')},
                  'average': {0: 1.4158309812874796, 1: 1.4293226152856995},
                  'stdev': {0: 0.5721450460404708, 1: 0.5771658975429514}})

plt.errorbar(df.timestamp.values, df.average.values, yerr=df.stdev.values)

plt.show()
person ImportanceOfBeingErnest    schedule 30.07.2018
comment
спасибо, использование timestamp.values решило эту проблему, однако есть ли у вас идеи, почему это иногда необходимо? почему ошибка значит? - person sds; 31.07.2018
comment
Я бы не слишком беспокоился об ошибке. По сути, временная метка преобразуется в число, которое не соответствует формату, который требуется matplotlib для даты и времени. Это связано с тем, что используется Series. Просто учтите тот факт, что вы можете часто использовать Series в matplotlib как деталь реализации, я не имею в виду, что они официально поддерживаются. - person ImportanceOfBeingErnest; 31.07.2018
comment
tbh, я в шоке от того, что что-то может работать с s.values, но не с s, и это не считается ошибкой. - person sds; 07.08.2018
comment
Тот факт, что библиотека A не принимает объект библиотеки B в качестве входных данных, будет ошибкой только в том случае, если библиотека A заявит, что это возможно. Pandas не зависит от matplotlib. Это затрудняет тестирование всех возможных комбинаций объектов pandas и функций построения графиков matplotlib. Существует тенденция внутреннего преобразования любого объекта pandas в массив numpy, но это все еще продолжается. Пока вам нужно сделать преобразование самостоятельно, что довольно просто. - person ImportanceOfBeingErnest; 08.08.2018