Я хочу иметь возможность устанавливать основные и второстепенные xticks и их метки для графика временных рядов, построенного из объекта временного ряда Pandas.
На странице "Что нового" в Pandas 0.9 говорится:
"вы можете использовать to_pydatetime или зарегистрировать конвертер для типа Timestamp"
но я не могу понять, как это сделать, чтобы использовать команды matplotlib ax.xaxis.set_major_locator
и ax.xaxis.set_major_formatter
(и второстепенные).
Если я использую их без преобразования времени панд, отметки и метки оси x окажутся неправильными.
Используя параметр xticks, я могу передать основные отметки в pandas.plot, а затем установить основные ярлыки отметок. Я не могу понять, как делать мелкие тики с помощью этого подхода. (Я могу установить метки на второстепенные отметки по умолчанию, установленные pandas.plot)
Вот мой тестовый код:
import pandas
print 'pandas.__version__ is ', pandas.__version__
print 'matplotlib.__version__ is ', matplotlib.__version__
dStart = datetime.datetime(2011,5,1) # 1 May
dEnd = datetime.datetime(2011,7,1) # 1 July
dateIndex = pandas.date_range(start=dStart, end=dEnd, freq='D')
print "1 May to 1 July 2011", dateIndex
testSeries = pandas.Series(data=np.random.randn(len(dateIndex)),
index=dateIndex)
ax = plt.figure(figsize=(7,4), dpi=300).add_subplot(111)
testSeries.plot(ax=ax, style='v-', label='first line')
# using MatPlotLib date time locators and formatters doesn't work with new
# pandas datetime index
ax.xaxis.set_minor_locator(matplotlib.dates.WeekdayLocator(byweekday=(1),
interval=1))
ax.xaxis.set_minor_formatter(matplotlib.dates.DateFormatter('%d\n%a'))
ax.xaxis.grid(True, which="minor")
ax.xaxis.grid(False, which="major")
ax.xaxis.set_major_formatter(matplotlib.dates.DateFormatter('\n\n\n%b%Y'))
plt.show()
# set the major xticks and labels through pandas
ax2 = plt.figure(figsize=(7,4), dpi=300).add_subplot(111)
xticks = pandas.date_range(start=dStart, end=dEnd, freq='W-Tue')
print "xticks: ", xticks
testSeries.plot(ax=ax2, style='-v', label='second line',
xticks=xticks.to_pydatetime())
ax2.set_xticklabels([x.strftime('%a\n%d\n%h\n%Y') for x in xticks]);
# set the text of the first few minor ticks created by pandas.plot
# ax2.set_xticklabels(['a','b','c','d','e'], minor=True)
# remove the minor xtick labels set by pandas.plot
ax2.set_xticklabels([], minor=True)
# turn the minor ticks created by pandas.plot off
# plt.minorticks_off()
plt.show()
print testSeries['6/4/2011':'6/7/2011']
и его вывод:
pandas.__version__ is 0.9.1.dev-3de54ae
matplotlib.__version__ is 1.1.1
1 May to 1 July 2011 <class 'pandas.tseries.index.DatetimeIndex'>
[2011-05-01 00:00:00, ..., 2011-07-01 00:00:00]
Length: 62, Freq: D, Timezone: None
xticks: <class 'pandas.tseries.index.DatetimeIndex'>
[2011-05-03 00:00:00, ..., 2011-06-28 00:00:00]
Length: 9, Freq: W-TUE, Timezone: None
2011-06-04 -0.199393
2011-06-05 -0.043118
2011-06-06 0.477771
2011-06-07 -0.033207
Freq: D
Обновление: я смог приблизиться к макету, который хотел, используя цикл для создания основных меток xtick:
# only show month for first label in month
month = dStart.month - 1
xticklabels = []
for x in xticks:
if month != x.month :
xticklabels.append(x.strftime('%d\n%a\n%h'))
month = x.month
else:
xticklabels.append(x.strftime('%d\n%a'))
Однако это немного похоже на использование оси x ax.annotate
: возможно, но не идеально.
источник
plot
функции pandas и установить все отметки после построения графика, используя методы matplotlib возвращаемогоax
объекта (например,ax.set_xticks
)?Ответы:
Оба
pandas
иmatplotlib.dates
используютmatplotlib.units
для обнаружения клещей.Но хотя
matplotlib.dates
есть удобные способы установить галочки вручную, pandas, похоже, до сих пор фокусируется на автоматическом форматировании (вы можете взглянуть на код для преобразования даты и форматирования в pandas).Так что на данный момент кажется более разумным использовать
matplotlib.dates
(как упомянул @BrenBarn в своем комментарии).import numpy as np import pandas as pd import matplotlib.pyplot as plt import matplotlib.dates as dates idx = pd.date_range('2011-05-01', '2011-07-01') s = pd.Series(np.random.randn(len(idx)), index=idx) fig, ax = plt.subplots() ax.plot_date(idx.to_pydatetime(), s, 'v-') ax.xaxis.set_minor_locator(dates.WeekdayLocator(byweekday=(1), interval=1)) ax.xaxis.set_minor_formatter(dates.DateFormatter('%d\n%a')) ax.xaxis.grid(True, which="minor") ax.yaxis.grid() ax.xaxis.set_major_locator(dates.MonthLocator()) ax.xaxis.set_major_formatter(dates.DateFormatter('\n\n\n%b\n%Y')) plt.tight_layout() plt.show()
(у меня немецкий язык, поэтому вторник [вт] становится Dienstag [Di])
источник