У меня есть фрейм данных Pandas, содержащий ежедневные данные для переменной за 3 года. Мне нужно построить линейную диаграмму, где ось X составляет от 1/1 до 12/31 (только месяц и день, без года) и имеет 3 линии, по одной для каждого года. Как мне построить это в matplotlib?
DateTime price
10 2007-10-06 35756.0
11 2007-10-06 34747.0
12 2007-10-07 35748.0
13 2007-10-07 34743.0
14 2007-10-08 35740.0
... ... ...
1519 2009-10-29 29564.0
1520 2009-10-30 32035.0
1521 2009-10-30 29397.0
1522 2009-10-31 32003.0
1523 2009-10-31 29256.0
Для приведенных выше данных мне нужно, чтобы на оси X были даты от 1/1 до 31 декабря и 3 строки, по одной для 2007, 2008 и 2009 годов.

Вы можете извлечь год и месяц-день (с помощью strftime ), затем сводную точку и график:
import pandas as pd
import numpy as np
# create a dummy dataset
df = pd.DataFrame({'DateTime': pd.date_range('2020-01-01', '2022-12-31'),
'price': np.sin(np.arange(1096)/80)
})
# if needed, ensure we have datetime
df['DateTime'] = pd.to_datetime(df['DateTime'])
# create new columns with year and month-day
# pivot and plot
(df.assign(year=lambda d: d['DateTime'].dt.year,
day=lambda d: d['DateTime'].dt.strftime('%m-%d')
)
.pivot(index='day', columns='year', values='price')
.plot()
)
Выход:
Вариант с seaborn.lineplot:
import seaborn as sns
import matplotlib.ticker as ticker
ax = sns.lineplot(data=df, x=df['DateTime'].dt.strftime('%m-%d'), y='price',
hue=df['DateTime'].dt.year)
ax.xaxis.set_major_locator(ticker.LinearLocator(10))
Выход:
Временной ряд с извлеченными годом и месяцем-днем:
DateTime price year day
0 2020-01-01 0.000000 2020 01-01
1 2020-01-02 0.012500 2020 01-02
2 2020-01-03 0.024997 2020 01-03
3 2020-01-04 0.037491 2020 01-04
4 2020-01-05 0.049979 2020 01-05
... ... ... ... ...
1091 2022-12-27 0.877742 2022 12-27
1092 2022-12-28 0.883663 2022 12-28
1093 2022-12-29 0.889445 2022 12-29
1094 2022-12-30 0.895088 2022 12-30
1095 2022-12-31 0.900592 2022 12-31
[1096 rows x 4 columns]
Другой вариант, который мог бы быть более удобным, — это установить общий високосный год (например, 2000) для построения графиков с использованием красивых отметок MonthLocator, а затем изменить формат, чтобы скрыть год:
import matplotlib.dates as mdates
ax = (df
.assign(year=lambda d: d['DateTime'].dt.year,
day=lambda d: d['DateTime'].add(pd.DateOffset(year=2000))
)
.pivot(index='day', columns='year', values='price')
.plot()
)
# add a tick for each month
ax.xaxis.set_major_locator(mdates.MonthLocator(interval=1))
# change the format to the month name
ax.xaxis.set_major_formatter(mdates.DateFormatter('%b'))
Выход:
Та же логика с seaborn:
import seaborn as sns
import matplotlib.dates as mdates
ax = sns.lineplot(data=df, x=df['DateTime'].add(pd.DateOffset(year=2000)),
y='price', hue=df['DateTime'].dt.year)
ax.xaxis.set_major_locator(mdates.MonthLocator(interval=1))
ax.xaxis.set_major_formatter(mdates.DateFormatter('%b'))
Выход:
Примечание. На всех графиках вы можете заметить небольшой разрыв в данных между 28 февраля и 1 марта для 2021 и 2022 годов, поскольку это не високосные годы.
Пожалуйста, предоставьте минимальный воспроизводимый пример данных.