2012-10-18 12 views
74

Chcę móc ustawić wielkie i mniejsze xticks oraz ich etykiety dla wykresu szeregów czasowych wykreślanych z obiektu szeregów czasowych Pandy.Ustawienie czasu szeregów pandy ustawiania osi x głównych i pomniejszych znaczników i etykiet

pandy 0.9 „co nowego” strona mówi:

„można użyć to_pydatetime lub zarejestrować konwerter typu timestamp”

ale nie mogę dowiedzieć się, jak aby to zrobić, aby móc używać poleceń matplotlib ax.xaxis.set_major_locator i (i mniejszych).

Jeśli użyję ich bez konwersji czasów pandy, tyknięcia i etykiety na osi X zepsują się.

Korzystając z parametru "xticks", mogę przesłać główne tiki do pandas.plot, a następnie ustawić główne znaczniki. Nie mogę się dowiedzieć, jak wykonać mniejsze tyknięcia przy użyciu tego podejścia. (Można ustawić etykiety na domyślnej drobnych kleszczy ustalonych przez pandas.plot)

Tu jest mój kodu testu:

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'] 

a jego produkcja:

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 

Graph with strange dates on xaxis

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 

Graph with correct dates

2011-06-04 -0.199393 
2011-06-05 -0.043118 
2011-06-06 0.477771 
2011-06-07 -0.033207 
Freq: D 

Aktualizacja: byłem w stanie zbliżyć się do układu chciałem za pomocą pętli do budowy wytwórni 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')) 

Jednak jest to trochę jak robi x -axis za pomocą ax.annotate: możliwe, ale nie idealne.

+1

wiem, że to naprawdę nie ma odpowiedzi na pytanie, ale jako ogólne podejście gdy Naprawdę zależy mi na tym, jak wygląda fabuła, generalnie po prostu staram się uzyskać jej wektorową wersję i sprawić, żeby wyglądała ładnie w programie Illustrator lub Inkscape. Odkryłem, że większość innych osób, które znam, robi to samo. –

+2

Czy możesz całkowicie zignorować argumenty funkcji parsa 'plot' i ustawić wszystkie tyknięcia po wykreślaniu, używając metod matplotlib zwróconego obiektu' ax' (np. 'Ax.set_xticks')? – BrenBarn

+0

@BrenBarn Nie mogłem dowiedzieć się, jak uzyskać datę jako datę Pythona zamiast datetime pand dla metod matplotlib. Odpowiedź bmu naprawia to, przekształcając daty przed spiskowaniem. – brenda

Odpowiedz

69

Zarówno pandas jak i matplotlib.dates używają do lokalizowania kleszczy.

Ale podczas matplotlib.dates posiada dogodne sposoby ustawienia ręcznie kleszczy, pandy wydaje się, że skupienie się na formatowanie auto tak daleko (może trzeba spojrzeć na code do dnia konwersji i formatowania w pand).

W tej chwili wydaje się bardziej uzasadnione użycie matplotlib.dates (jak wspomniano przez @BrenBarn w swoim komentarzu).

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() 

pandas_like_date_fomatting

(moja locale jest niemiecki, więc Wtorek [Wto] staje Dienstag [Di])

+0

Dzięki, jest to bardzo wyraźny przykład, jak używać matplotlib z danymi pandas timeseries. Nie zdawałem sobie sprawy, że możesz przekazać serię jako dane na matplotlib, tak jak ty. – brenda

Powiązane problemy