Eu quero ser capaz de definir os xticks principais e secundários e seus rótulos para um gráfico de série temporal traçado a partir de um objeto de série temporal Pandas.
A página "novidades" do Pandas 0.9 diz:
"você pode usar to_pydatetime ou registrar um conversor para o tipo de carimbo de data / hora"
mas não consigo descobrir como fazer isso para poder usar os comandos matplotlib ax.xaxis.set_major_locator
e ax.xaxis.set_major_formatter
(e secundários).
Se eu usá-los sem converter os tempos de pandas, os marcadores e os rótulos do eixo x acabam errados.
Usando o parâmetro 'xticks', posso passar as marcas principais para pandas.plot e, em seguida, definir os rótulos das marcas principais. Não consigo descobrir como fazer os pequenos tiques usando essa abordagem. (Eu posso definir os rótulos nas marcações secundárias padrão definidas por pandas.plot)
Aqui está meu código de teste:
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']
e sua saída:
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
Atualização: consegui chegar mais perto do layout que queria usando um loop para construir os principais rótulos 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'))
No entanto, é um pouco como fazer o eixo x usando ax.annotate
: possível, mas não ideal.
fonte
plot
função pandas e definir todos os tiques após a plotagem, usando métodos matplotlib doax
objeto retornado (por exemplo,ax.set_xticks
)?Respostas:
Ambos
pandas
ematplotlib.dates
usematplotlib.units
para localizar os carrapatos.Mas, embora
matplotlib.dates
tenha maneiras convenientes de definir os carrapatos manualmente, o pandas parece estar focado na formatação automática até agora (você pode dar uma olhada no código para conversão de data e formatação no pandas).Portanto, no momento, parece mais razoável de usar
matplotlib.dates
(como mencionado por @BrenBarn em seu comentário).(meu local é alemão, então terça-feira [ter] se torna Dienstag [Di])
fonte