Побудова дат на осі х за допомогою matplotlib Python


75

Я намагаюся скласти інформацію щодо дат. У мене є список дат у форматі "02.02.1991".

Я перетворив їх, виконавши наступне:

x = parser.parse(date).strftime('%Y%m%d'))

який дає 19910102

Потім я спробував використовувати num2date

import matplotlib.dates as dates
new_x = dates.num2date(x)

Ділянка:

plt.plot_date(new_x, other_data, fmt="bo", tz=None, xdate=True)

Але я отримую помилку. Там написано "ValueError: рік поза діапазоном". Будь-які рішення?


Ах, я дав поганий приклад дати. Насправді у мене в списку дат немає 31 грудня 2012 року. Я змінив його на 02 січня 1991 р.
irl_irl

2
довідка (num2date): "x - плаваюче значення, яке дає одиницю плюс кількість днів з 0001-01-01", тому x = 19910102 не відповідає 02 січня 1991 р.
Kyss Tao

Що таке парсер у цьому питанні?
Джон Сноу

Відповіді:


22

Як вже говорив @KyssTao, він каже, help(dates.num2date)що це xповинен бути плаваючий показник, що дає кількість днів з 0001-01-01 плюс один. Отже,19910102 це не 2 / січня / 1991 р., Оскільки, якщо порахувати 19910101 день з 0001-01-01, ти отримаєш щось у 54513 році або подібному (поділи на 365,25, кількість днів у році).

datestr2numЗамість цього використовуйте (див. help(dates.datestr2num)):

new_x = dates.datestr2num(date) # where date is '01/02/1991'

2
Було б непогано, якби ви також могли додати importзаяву, щоб допомогти новачкам python, таким як я.
kkuilla

145

Ви можете зробити це більш просто, використовуючи plot()замість plot_date().

Спочатку перетворіть свої рядки на екземпляри Python datetime.date:

import datetime as dt

dates = ['01/02/1991','01/03/1991','01/04/1991']
x = [dt.datetime.strptime(d,'%m/%d/%Y').date() for d in dates]
y = range(len(x)) # many thanks to Kyss Tao for setting me straight here

Потім побудуйте графік:

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

plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%m/%d/%Y'))
plt.gca().xaxis.set_major_locator(mdates.DayLocator())
plt.plot(x,y)
plt.gcf().autofmt_xdate()

Результат:

введіть тут опис зображення


10
@bernie Дякую, це мені дуже допомогло. Однак у моїй проблемі у мене занадто багато днів, тому вся ділянка засмічується. Як показати кожну п’яту дату або кожну десяту дату на осі х за допомогою вашого методу?
user1506145

1
@erik Я знаю, що це трохи пізно, але я видалив два рядки set_major, і це для мене це прояснило. Втратили деяку функціональність, але все-таки вдосконалення.
TheBoro

1
На жаль, він показує мені не 3 дати, а 6 інших дат (у цей інтервал). Використання matplotlib-1.5.1
Groosha

41

У мене занадто низька репутація, щоб додати коментар до відповіді @bernie із відповіддю на @ user1506145. Я натрапив на те саме питання.

1

Відповідь на це - інтервальний параметр, який все виправляє

2

import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import numpy as np
import datetime as dt

np.random.seed(1)

N = 100
y = np.random.rand(N)

now = dt.datetime.now()
then = now + dt.timedelta(days=100)
days = mdates.drange(now,then,dt.timedelta(days=1))

plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))
plt.gca().xaxis.set_major_locator(mdates.DayLocator(interval=5))
plt.plot(days,y)
plt.gcf().autofmt_xdate()
plt.show()

1
Зверніть увагу, що якщо ви берете першу дату серії чи індексу та останню дату, то, оскільки це діапазон, остання дата буде обрізаною, і у вас виникнуть помилки з вашим кодом. Припускаючи , що у вас є Dateстовпець на індексі, то ви можете зробити: days = mdates.drange(d1.index.min(),d1.index.max() + dt.timedelta(days=1),dt.timedelta(days=1)). По суті, я додав 1 день до дати верхнього значення діапазону.
Девід Еріксон,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.