2012-07-20 39 views
8

Używam funkcji imshow() matplotlib, aby pokazać pandas.DataFrame.pandy, matplotlib, używaj indeksu ramek danych jako etykiet podziałki osi

Chciałbym, aby etykiety i tyknięcia dla osi X i Y były rysowane z list DataFrame.index i DataFrame.columns, ale nie mogę wymyślić, jak to zrobić.

Zakładając, że data jest pandas.DataFrame:

>>> print data 
<class 'pandas.core.frame.DataFrame'> 
Index: 201 entries, 1901 to 2101 
Data columns: 
jan 201 non-null values 
feb 201 non-null values 
mar 201 non-null values 
apr 201 non-null values 
may 201 non-null values 
jun 201 non-null values 
jul 201 non-null values 
aug 201 non-null values 
sep 201 non-null values 
oct 201 non-null values 
nov 201 non-null values 
dec 201 non-null values 

Kiedy to zrobić:

ax1 = fig.add_subplot(131, xticklabels=data.columns, yticklabels=data.index) 
ax1.set_title("A") 
ax1.tick_params(axis='both', direction='out') 
im1 = ax1.imshow(data, 
       interpolation='nearest', 
       aspect='auto', 
       cmap=cmap) 

I skończyć z dobrze rozmieszczonymi etykiet podziałki na osi y obrazu, ale etykiety są 1901-1906 zamiast 1901 do 2101. Podobnie, znacznikami osi X są feb-jul zamiast jan-dec.

Jeśli użyć

ax1 = fig.add_subplot(131) # without specifying tick labels 

Wtedy kończy się z etykiety osi kleszczy Samo przetwarzanych wartości indeksu ndarray (tj 0-201 i 0-12). Nie muszę modyfikować odstępów lub ilości znaczników i etykiet, chcę tylko, aby tekst etykiety pochodził z indeksu DataFrame i list kolumn. Nie jestem pewien, czy brakuje mi czegoś łatwego, czy nie?

Z góry dziękuję.

Odpowiedz

5

jako rozwiązanie ogólne, znalazłem następującą metodę, aby być łatwym sposobem przynieść indeksu Pandas datetime64 na etykietę osi matplotlib.

Najpierw utwórz nową serię, konwertując indeks datetime64 pandy na klasę datetime.datetime Pythona.

new_series = your_pandas_dataframe.index.to_pydatetime()

Teraz masz pełną funkcjonalność matplotlib.dates. Przed rozpoczęciem drukowania zaimportuj matplotlib.terminach mdates i zadeklarować następujące zmienne:

years = mdates.YearLocator() 
months = mdates.MonthLocator() 
days = mdates.DayLocator() 
hours = mdates.HourLocator(12) #if you want ticks every 12 hrs, you can pass 12 to this function 
minutes = mdates.MinuteLocator() 
daysFmt = mdates.DateFormatter('%m/%d') #or whatever format you want 

Teraz, tworzyć wykresy, korzystając z new_series jako Oś X:

fig1 = plt.figure() 
ax = fig1.add_subplot(111) 
ax.plot(new_series,your_pandas_dataframe) 

Można wykorzystać funkcje mdates zadeklarowanych powyżej dostosować etykiety i spełnia twoje przyjemne cechy, takie jak:

ax.xaxis.set_major_locator(days) 
ax.xaxis.set_major_formatter(daysFmt) 
ax.xaxis.set_minor_locator(hours) 
6

Uważam, że problem związany jest z określaniem etykiet zaznaczania dla istniejących kleszczy. Domyślnie jest mniej znaczników niż etykiet, więc używane są tylko pierwsze etykiety. Następujące czynności powinny działać, najpierw ustawiając liczbę kleszczy.

ax1 = fig.add_subplot(131) 
ax1.set_title("A") 
ax1.tick_params(axis='both', direction='out') 
ax1.set_xticks(range(len(data.columns))) 
ax1.set_xticklabels(data.columns) 
ax1.set_yticks(range(len(data.index))) 
ax1.set_yticklabels(data.index) 
im1 = ax1.imshow(data, interpolation='nearest', aspect='auto', cmap=cmap) 

Powoduje to utworzenie znacznika dla każdego roku na osi Y, więc możesz chcieć użyć podzestawu wartości indeksu.

+0

Jest to najbardziej ogólne rozwiązanie - nie ma potrzeby hackowania DateTime itp. – FuzzyDuck

3

Znalazłem, że najłatwiej to zrobić z ImageGrid. Oto kod, aby to zrobić i fabuła + here is an IPython notebook że pokazuje go w bardziej reprezentacyjny formacie:

mons = ['Jan', 
'Feb', 
'Mar', 
'Apr', 
'May', 
'Jun', 
'Jul', 
'Aug', 
'Sep', 
'Oct', 
'Nov', 
'Dec'] 

# just get the first 5 for illustration purposes 
df = DataFrame(randn(201, len(mons)), columns=mons, 
       index=arange(1901, 2102))[:5] 

from mpl_toolkits.axes_grid1 import ImageGrid 
fig = figure(figsize=(20, 100)) 
grid = ImageGrid(fig, 111, nrows_ncols=(1, 1), 
       direction='row', axes_pad=0.05, add_all=True, 
       label_mode='1', share_all=False, 
       cbar_location='right', cbar_mode='single', 
       cbar_size='10%', cbar_pad=0.05) 

ax = grid[0] 
ax.set_title('A', fontsize=40) 
ax.tick_params(axis='both', direction='out', labelsize=20) 
im = ax.imshow(df.values, interpolation='nearest', vmax=df.max().max(), 
       vmin=df.min().min()) 
ax.cax.colorbar(im) 
ax.cax.tick_params(labelsize=20) 
ax.set_xticks(arange(df.shape[1])) 
ax.set_xticklabels(mons) 
ax.set_yticks(arange(df.shape[0])) 
ax.set_yticklabels(df.index) 

enter image description here

Powiązane problemy