Сюжет с Matplotlib с использованием List - Datetime - различное поведение в формате - PullRequest
0 голосов
/ 07 февраля 2019

Почему Matplotlib имеет такое странное поведение с типом данных Date?

Matplotlib позволяет вам изначально составлять графики Python Datetime и по большей части делает хороший тик выбора работыместоположения и строковые форматы.Из документации"Устранение общих раздражителей дат"

Я также прочитал этот вопрос , который дал мне некоторые подсказки, связанные с Формат даты Matplotlib .Я также прочитал вопросы с наибольшим количеством голосов о matplotlib и Datetime, но я все еще не понимаю следующее поведение.

#timestamp is a <class 'list'>
timestamp=['2019-02-04', '2019-01-15', '2018-10-08', '2018-07-09',
           '2018-04-09', '2018-02-08', '2017-09-08', '2017-09-08',
           '2017-07-07', '2017-04-07', '2017-01-09', '2016-10-07',
           '2016-07-01', '2016-03-25', '2015-12-27', '2015-09-25',
           '2015-06-26', '2015-03-27', '2014-12-24', '2014-10-06',
           '2014-07-02', '2014-03-28', '2013-12-20', '2013-09-27',
           '2013-06-11', '2013-03-27', '2012-12-27', '2012-09-26',
           '2012-06-13', '2012-03-28', '2011-12-14', '2011-09-28',
           '2011-06-14', '2011-03-30', '2010-12-15', '2010-09-29',
           '2010-06-19', '2010-03-31', '2009-12-29', '2009-09-30',
           '2009-06-17', '2009-04-01', '2008-12-20', '2008-08-25',
           '2008-08-25', '2008-06-19', '2008-03-19', '2008-03-19',
           '2006-04-11', '2005-12-27', '2005-09-28', '2005-07-02',
           '2005-04-20', '2004-12-21', '2004-10-20', '2004-07-21',
           '2003-09-22', '2003-08-20', '2002-12-31']

#time_python is a <class 'datetime.datetime'>
time_python=[datetime.strptime(d, "%Y-%m-%d") for d in timestamp]
#time_series is a <class 'pandas.core.indexes.datetimes.DatetimeIndex'>
time_series=pd.to_datetime(timestamp)

array=np.arange(1,len(timestamp)+1) 

time_2_num=mdates.date2num(time_series.to_pydatetime())

#First plot using the List Format as x axes
plt.subplot(411)
plt.bar(timestamp,array)
plt.xticks(rotation='vertical')

#Second plot using the padas Datatime Format as x axes
plt.subplot(412)
plt.bar(time_series,array)
plt.xticks(rotation='vertical')
plt.subplots_adjust(hspace = 1.2)

#Third plot using the DateTime Format as x axes 
plt.subplot(413)
plt.bar(time_python,array)
plt.xticks(rotation='vertical')
plt.subplots_adjust(hspace = 1.2)

#Fourth plot using the Matplot Date Format as x axes 
plt.subplot(414)
plt.bar(time_2_num,array)
plt.xticks(rotation='vertical')
plt.subplots_adjust(hspace = 1.2)

plt.gcf().autofmt_xdate()  

plt.show()

Желаемый результат, очевидно, является первым графиком.

enter image description here

Я хочу лучше понять, почему барыграфика II, III, IV имеет это представление, отличное от I. Вход y одинаков для 4 графиков.

Ответы [ 2 ]

0 голосов
/ 07 февраля 2019

Во-первых, разница станет более очевидной, если вы удалите линию plt.gcf().autofmt_xdate(), потому что это удалит метки со всех, кроме последнего графика.

enter image description here

Первый сюжет

Первый сюжет является «категоричным» сюжетом.Значения для оси x являются строками.Они показываются один за другим в том порядке, в котором они появляются во входном списке / массиве, и каждый получает свою метку.В этом случае matplotlib не знает, что строки представляют даты, и вы также можете вместо этого предоставить список фруктов (["Apple", "Banana", "Cherry", ...])

Второй / Третий участок

Это и есть предполагаемое поведение для графиков даты и времени в matplotlib.Matplotlib одинаково хорошо работает с datetime или numpy.datetime64 объектами.Ось представляет собой истинный масштаб в смысле линии с определенной линейной метрикой (то есть расстояние между понедельником и средой в два раза больше, чем между субботой и воскресеньем).Что касается единиц таких осей даты и времени, то в документации указано

Matplotlib представляет даты с использованием чисел с плавающей запятой, указывающих количество дней с 0001-01-01 UTC, плюс 1.

Поскольку matplotlib распознает ввод даты и времени, он автоматически выберет локатор и форматировщик даты, чтобы иметь метки в полезных местах

Четвертый график

Четвертый сюжет в принципе идентичен двум приведенным выше.Единственная разница в том, что у matplotlib нет шансов узнать, что числа (например, 731000) предназначены для обозначения дат (они также могут быть расстояниями между Землей и спутниками).

Вы все еще можете получить тот же внешний вид, что и на двух графиках выше, вручную установив локатор и форматер, например, добавив следующие строки к последнему графику

loc = mdates.AutoDateLocator()
plt.gca().xaxis.set_major_locator(loc)
plt.gca().xaxis.set_major_formatter(mdates.AutoDateFormatter(loc))

приведет к тому же графикукак второй, третий сюжет

enter image description here

0 голосов
/ 07 февраля 2019

Для первого графика вы отправляете timestamp, который является чисто строками.Matplotlib рассматривает это как строки.Если вы посмотрите на график сам по себе, вы увидите, что метки - это просто строки из timestamp в том же порядке.

Другие 3 метода преобразуют эту строку в метки времени, которые matplotlib обрабатывает по-разному.

timestamp=['2019-02-04', '2019-01-15', '2018-10-08', '2018-07-09',
       '2018-04-09', '2018-02-08', '2017-09-08', '2017-09-08',
       '2017-07-07', '2017-04-07', '2017-01-09', '2016-10-07',
       '2016-07-01', '2016-03-25', '2015-12-27', '2015-09-25',
       '2015-06-26', '2015-03-27', '2014-12-24', '2014-10-06',
       '2014-07-02', '2014-03-28', '2013-12-20', '2013-09-27',
       '2013-06-11', '2013-03-27', '2012-12-27', '2012-09-26',
       '2012-06-13', '2012-03-28', '2011-12-14', '2011-09-28',
       '2011-06-14', '2011-03-30', '2010-12-15', '2010-09-29',
       '2010-06-19', '2010-03-31', '2009-12-29', '2009-09-30',
       '2009-06-17', '2009-04-01', '2008-12-20', '2008-08-25',
       '2008-08-25', '2008-06-19', '2008-03-19', '2008-03-19',
       '2006-04-11', '2005-12-27', '2005-09-28', '2005-07-02',
       '2005-04-20', '2004-12-21', '2004-10-20', '2004-07-21',
       '2003-09-22', '2003-08-20', '2002-12-31']

array=np.arange(1,len(timestamp)+1) 
plt.bar(timestamp,array)
plt.xticks(rotation='vertical')
fig = plt.gcf()
fig.set_size_inches(18.5, 10.5)

enter image description here

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