2014-11-02 10 views
15

Wystarczy popatrzeć na poniższym wykresie: enter image description herematplotlib widać X-Tick etykiety nakładające mimo najlepszych starań

Jest to poletko z tym większego rysunku: enter image description here

Widzę dwa problemy z nim. Po pierwsze, etykiety osi X nakładają się na siebie (to jest mój główny problem). Druga. położenie mniejszych linii siatki w osi x wydaje się nieco niewyraźne. Po lewej stronie wykresu wyglądają na odpowiednio rozmieszczone. Ale z prawej strony wydają się tłoczyć główne linie siatki ... tak, jakby główne lokalizacje linii siatki nie były poprawnymi wielokrotnościami mniej znaczących lokalizacji.

Moja konfiguracja jest taka, że ​​mam DataFrame nazywa df który ma DatetimeIndex na wiersze i kolumny o nazwie value który zawiera pływaków. W razie potrzeby mogę podać przykład treści z df. Kilkanaście linii df znajduje się na dole tego wpisu.

Oto kod, który tworzy postać:

now = dt.datetime.now() 

fig, axes = plt.subplots(2, 2, figsize=(15, 8), dpi=200) 
for i, d in enumerate([360, 30, 7, 1]): 
    ax = axes.flatten()[i] 
    earlycut = now - relativedelta(days=d) 
    data = df.loc[df.index>=earlycut, :] 
    ax.plot(data.index, data['value']) 
    ax.xaxis_date() 

    ax.get_xaxis().set_minor_locator(mpl.ticker.AutoMinorLocator()) 
    ax.get_yaxis().set_minor_locator(mpl.ticker.AutoMinorLocator()) 

    ax.grid(b=True, which='major', color='w', linewidth=1.5) 
    ax.grid(b=True, which='minor', color='w', linewidth=0.75) 

Co jest moim najlepszym rozwiązaniem tutaj, aby uzyskać etykiety osi x, aby zatrzymać zachodziły na siebie (w każdym z czterech wątków)? Ponadto, oddzielnie (ale mniej pilnie), co się dzieje z drobnym problemem kleszczowym w lewym górnym wątku?

Jestem na Pandach 0.13.1, numpy 1.8.0 i matplotlib 1.4.x.

Oto niewielki fragment df dla odniesienia:

        id scale tempseries_id value 
timestamp               
2014-11-02 14:45:10.302204+00:00 7564  F    1 68.0000 
2014-11-02 14:25:13.532391+00:00 7563  F    1 68.5616 
2014-11-02 14:15:12.102229+00:00 7562  F    1 68.9000 
2014-11-02 14:05:13.252371+00:00 7561  F    1 69.0116 
2014-11-02 13:55:11.792191+00:00 7560  F    1 68.7866 
2014-11-02 13:45:10.782227+00:00 7559  F    1 68.6750 
2014-11-02 13:35:10.972248+00:00 7558  F    1 68.4500 
2014-11-02 13:25:10.362213+00:00 7557  F    1 68.1116 
2014-11-02 13:15:10.822247+00:00 7556  F    1 68.2250 
2014-11-02 13:05:10.102200+00:00 7555  F    1 68.5616 
2014-11-02 12:55:10.292217+00:00 7554  F    1 69.0116 
2014-11-02 12:45:10.382226+00:00 7553  F    1 69.3500 
2014-11-02 12:35:10.642245+00:00 7552  F    1 69.2366 
2014-11-02 12:25:12.642255+00:00 7551  F    1 69.1250 
2014-11-02 12:15:11.122382+00:00 7550  F    1 68.7866 
2014-11-02 12:05:11.332224+00:00 7549  F    1 68.5616 
2014-11-02 11:55:11.662311+00:00 7548  F    1 68.2250 
2014-11-02 11:45:11.122193+00:00 7547  F    1 68.4500 
2014-11-02 11:35:11.162271+00:00 7546  F    1 68.7866 
2014-11-02 11:25:12.102211+00:00 7545  F    1 69.2366 
2014-11-02 11:15:10.422226+00:00 7544  F    1 69.4616 
2014-11-02 11:05:11.412216+00:00 7543  F    1 69.3500 
2014-11-02 10:55:10.772212+00:00 7542  F    1 69.1250 
2014-11-02 10:45:11.332220+00:00 7541  F    1 68.7866 
2014-11-02 10:35:11.332232+00:00 7540  F    1 68.5616 
2014-11-02 10:25:11.202411+00:00 7539  F    1 68.2250 
2014-11-02 10:15:11.932326+00:00 7538  F    1 68.5616 
2014-11-02 10:05:10.922229+00:00 7537  F    1 68.9000 
2014-11-02 09:55:11.602357+00:00 7536  F    1 69.3500 

Edit: Próba fig.autofmt_xdate(): I nie sądzę, że to będzie rade. Wydaje się, że używają tych samych etykiet x-tick dla obu wykresów po lewej stronie, a także dla obu wykresów po prawej. Co nie jest poprawne, biorąc pod uwagę moje dane. Proszę zobaczyć wyjście problematyczne poniżej:

enter image description here

Odpowiedz

14

Ok, w końcu to działa. Sztuką było użycie plt.setp do ręcznego obracania etykiet. Używanie fig.autofmt_xdate() nie działa tak, jak robi nieoczekiwane rzeczy, gdy masz wiele wątków na rysunku. Oto kod pracy z jego wyjścia:

for i, d in enumerate([360, 30, 7, 1]): 
    ax = axes.flatten()[i] 
    earlycut = now - relativedelta(days=d) 
    data = df.loc[df.index>=earlycut, :] 
    ax.plot(data.index, data['value']) 

    ax.get_xaxis().set_minor_locator(mpl.ticker.AutoMinorLocator()) 
    ax.get_yaxis().set_minor_locator(mpl.ticker.AutoMinorLocator()) 

    ax.grid(b=True, which='major', color='w', linewidth=1.5) 
    ax.grid(b=True, which='minor', color='w', linewidth=0.75) 

    plt.setp(ax.get_xticklabels(), rotation=30, horizontalalignment='right') 

fig.tight_layout() 

enter image description here

Nawiasem mówiąc, komentarz wcześniej o pewnych rzeczach matplotlib biorących zawsze jest bardzo interesujące tutaj. Używam malinowego pi do działania jako stacja pogodowa w odległej lokalizacji. Gromadzi dane i udostępnia wyniki za pośrednictwem Internetu. I chłopcze, chłopcze, to naprawdę świszczą, próbując zgasić te grafiki.

7

Ze względu na sposób renderowania tekstu jest obsługiwana w matplotlib, automatyczne wykrywanie nakładających się tekst naprawdę spowalnia rzeczy w dół. (Przestrzeń, którą zajmuje tekst, nie może być dokładnie obliczona, dopóki nie zostanie narysowana.) Z tego powodu matplotlib nie próbuje tego automatycznie.

Dlatego najlepiej obracać długie etykiety zaznaczania. Ponieważ daty najczęściej mają ten problem, istnieje metoda liczbowa, która obraca (między innymi) etykiety zaznaczenia, aby uczynić je bardziej czytelnymi. (Uwaga: Jeśli używasz metody pandy plot, zwraca obiekt osi, więc musisz użyć ax.figure.autofmt_xdate().)

Jako szybki przykład:

import numpy as np 
import pandas as pd 
import matplotlib.pyplot as plt 

time = pd.date_range('01/01/2014', '4/01/2014', freq='H') 
values = np.random.normal(0, 1, time.size).cumsum() 

fig, ax = plt.subplots() 
ax.plot_date(time, values, marker='', linestyle='-') 

fig.autofmt_xdate() 
plt.show() 

Gdybyśmy byli opuścić fig.autofmt_xdate() Wymeldowanie:

enter image description here

A jeśli używamy fig.autofmt_xdate():

enter image description here

+0

Czy to rozwiązanie działa dla kilku podpól (powiedzmy tablica 2x2) z różnymi osiami czasu na wszystkich? – 8one6

+0

(Próbowałem zaimplementować to rozwiązanie, ale wyświetlają one tylko etykiety zaznaczeń w dolnym rzędzie podpól, a te nie odpowiadają prawidłowo w górnym rzędzie podpól). – 8one6