2014-11-02 14 views
15

Date un'occhiata al grafico qui sotto: enter image description herematplotlib etichette mostrando x-tick sovrapposti nonostante gli sforzi

E 'una sottotrama di questa figura più grande: enter image description here

vedo due problemi con esso. Innanzitutto, le etichette dell'asse x si sovrappongono l'una all'altra (questo è il mio problema principale). Secondo. la posizione delle griglie minori dell'asse x sembra un po 'fastidiosa. A sinistra del grafico, appaiono correttamente distanziati. Ma a destra, sembrano affollare le griglie principali ... come se le posizioni delle griglie principali non fossero i multipli corretti delle posizioni secondarie.

mia messa a punto è che ho un dataframe chiamato df che ha un DatetimeIndex sulle righe e una colonna chiamata value che contiene galleggianti. Posso fornire un esempio del contenuto di df in un elenco, se necessario. Una dozzina di linee di df sono in fondo a questo post per riferimento.

Ecco il codice che produce la cifra:

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) 

Qual è il mio migliore opzione qui per ottenere le etichette di asse x per fermare sovrapposte l'un l'altro (in ciascuno dei quattro sottotrame)? Inoltre, separatamente (ma meno urgentemente), cosa succede con il problema di tick secondario nella sottotramma in alto a sinistra?

Sono su Pandas 0.13.1, numpy 1.8.0 e matplotlib 1.4.x.

Ecco un piccolo frammento di df per riferimento:

        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: Cercando fig.autofmt_xdate(): Io non credo che questo sta per fare il trucco. Sembra che utilizzi le stesse etichette x-tick per entrambi i grafici a sinistra e anche per entrambi i grafici a destra. Quale non è corretto dati i miei dati. Si prega di vedere l'output problematico sotto:

enter image description here

risposta

14

Ok, finalmente ho funzionato. Il trucco consisteva nell'usare plt.setp per ruotare manualmente le etichette di graduazione. L'utilizzo di fig.autofmt_xdate() non ha funzionato in quanto comporta alcune impreviste quando si dispone di più sottotrame nella figura. Ecco il codice a lavorare con la sua uscita:

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

A proposito, il commento precedente su alcune cose matplotlib prendendo sempre è molto interessante. Sto usando un pi lampone per fungere da stazione meteorologica in una postazione remota. Sta raccogliendo i dati e servendo i risultati via web. E ragazzo oh ragazzo, sta davvero ansimando cercando di far uscire questi grafici.

7

A causa del rendering del testo modo in cui viene gestita in matplotlib, rilevamento automatico di testo sovrapposizione rallenta veramente le cose. (Lo spazio occupato dal testo non può essere calcolato con precisione fino a quando non è stato disegnato.) Per questo motivo, matplotlib non tenta di farlo automaticamente.

Pertanto, è meglio ruotare le etichette con le tacche lunghe. Poiché le date più comunemente hanno questo problema, c'è un metodo di figura fig.autofmt_xdate() che (tra le altre cose) ruoterà le etichette di spunta per renderle un po 'più leggibili. (Nota: se stai usando un metodo panda plot, restituisce un oggetto axes, quindi dovrai usare ax.figure.autofmt_xdate().)

Come un rapido esempio:

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

Se dovessimo lasciare fig.autofmt_xdate() out:

enter image description here

E se usiamo fig.autofmt_xdate():

enter image description here

+0

Questa soluzione funziona per diverse sottotrame (ad esempio un array 2x2) con diversi assi di data e ora su tutti? – 8one6

+0

(Ho provato ad implementare questa soluzione, ma mostra solo le etichette di graduazione nella riga inferiore delle sottotrame e quelle non corrispondono correttamente alla riga superiore delle sottotrame.) – 8one6

Problemi correlati