2014-07-10 16 views
5

Dire che ho un dataframe df dove df.index consiste di datetime oggetti, ad es.Inistenze di plottaggio nella serie storica in Panda

> df.index[0] 
datetime.date(2014, 5, 5) 

Se ho tracciarla Pandas ben conserva la tipologia datetime nella trama, che permette all'utente di modificare il campionamento di serie temporali, nonché opzioni di formattazione della trama:

# Plot the dataframe: 
    f  = plt.figure(figsize=(8,8)) 
    ax = f.add_subplot(1,1,1) 
    lines = df.plot(ax=ax) 

    # Choose the sampling rate in terms of dates: 
    ax.xaxis.set_major_locator(matplotlib.dates.WeekdayLocator(byweekday=(0,1,2,3,4,5,6), 
                  interval=1)) 

    # We can also re-sample the X axis numerically if we want (e.g. every 4 steps): 
    N = 4 

    ticks  = ax.xaxis.get_ticklocs() 
    ticklabels = [l.get_text() for l in ax.xaxis.get_ticklabels()] 

    ax.xaxis.set_ticks(ticks[-1::-N][::-1]) 
    ax.xaxis.set_ticklabels(ticklabels[-1::-N][::-1]) 

    # Choose a date formatter using a date-friendly syntax: 
    ax.xaxis.set_major_formatter(matplotlib.dates.DateFormatter('%b\n%d')) 

    plt.show() 

Tuttavia, il sopra fa non lavoro per boxplot (le etichette di graduazione per l'asse x sono resi vuoto) :

df2.boxplot(column='A', by='created_dt',ax=ax, sym="k.") 

# same code as above ... 

Nell'esempio precedente, Pandas converte le etichette dell'asse x in string, quindi il formatter e i localizzatori non funzionano più.

questo post ri-utilizza soluzioni dalle seguenti thread:

  1. risposta accettata a Pandas timeseries plot setting x-axis major and minor ticks and labels
  2. risposta accettata a Pandas: bar plot xtick frequency

Perché? Come posso usare boxplot in un modo che mi permetta di usare i localizzatori e i formattatori di date matplotlib?

risposta

6

No, in realtà anche la trama linea non funziona correttamente, se avete l'anno presentarsi, si noterà il problema: invece di essere 2000 nella seguente esempio, i xticks sono nel 1989.

In [49]: 
df=pd.DataFrame({'Val': np.random.random(50)}) 
df.index=pd.date_range('2000-01-02', periods=50) 
f  = plt.figure() 
ax = f.add_subplot(1,1,1) 
lines = df.plot(ax=ax) 
ax.xaxis.set_major_formatter(matplotlib.dates.DateFormatter('%y%b\n%d')) 
print ax.get_xlim() 
(10958.0, 11007.0) 

enter image description here

In [50]: 
matplotlib.dates.strpdate2num('%Y-%M-%d')('2000-01-02') 
Out[50]: 
730121.0006944444 
In [51]: 
matplotlib.dates.num2date(730121.0006944444) 
Out[51]: 
datetime.datetime(2000, 1, 2, 0, 1, tzinfo=<matplotlib.dates._UTC object at 0x051FA9F0>) 

Risulta dati datetime viene gestito in modo diverso in pandas e matplotlib: in quest'ultimo, 2000-1-2 dovrebbe essere 730121.0006944444, anziché 10958.0 in pandas

Per farlo bene abbiamo bisogno di evitare di usare pandas s' plot metodo:

In [52]: 
plt.plot_date(df.index.to_pydatetime(), df.Val, fmt='-') 
ax=plt.gca() 
ax.xaxis.set_major_formatter(matplotlib.dates.DateFormatter('%y%b\n%d')) 

enter image description here

Allo stesso modo per barplot:

In [53]: 
plt.bar(df.index.to_pydatetime(), df.Val, width=0.4) 
ax=plt.gca() 
ax.xaxis.set_major_formatter(matplotlib.dates.DateFormatter('%y%b\n%d')) 

enter image description here

+0

Grazie @CT Zhu. Comprendi che si tratta di un bug in Pandas o forse che fornisce una base per una richiesta di funzionalità? O ci sono argomenti per far funzionare Pandas in questo modo? –

+1

@ user815423426, questo è un vecchio problema, vedere un post correlato (e vecchio): http://stackoverflow.com/questions/12945971/pandas-timeseries-plot-set-x-axis-major-and-minor-ticks -e-etichette. Ho avuto difficoltà a considerare o meno un bug, come vedi, il problema si riduce al fatto che 'pandas.tseries.index.DatetimeIndex' e' datetime.datetime' sono abbastanza diversi. Personalmente penso che i metodi 'plot 'di' pandas' sono utili per generare grafici quando si vuole usare as-is. Se voglio fare personalizzazione, preferisco usare 'matplotlib' direttamente. Una richiesta di funzionalità potrebbe essere utile. Saluti! –

Problemi correlati