2014-11-02 7 views
15

Werfen Sie einen Blick auf die folgende Grafik: enter image description hereMatplotlib zeigt x-tick Etiketten überlappende trotz Bemühungen

Es ist ein subplot dieser größeren Zahl: enter image description here

ich zwei Probleme mit ihm zu sehen. Erstens überschneiden sich die X-Achsen-Etiketten miteinander (das ist mein Hauptproblem). Zweite. Die Position der Minirasterlinien der x-Achse scheint ein wenig wackelig. Auf der linken Seite des Diagramms sehen sie richtig beabstandet aus. Aber auf der rechten Seite scheinen sie die Hauptgitternetze zu überfrachten ... als ob die Hauptgitternetzpositionen keine richtigen Vielfachen der kleineren Zeckenpositionen wären.

Meine Einrichtung ist, dass ich einen DataFrame mit der Bezeichnung df habe, der eine DatetimeIndex in den Zeilen und eine Spalte namens value enthält, die Floats enthält. Ich kann ein Beispiel für die df Inhalte in einem Kern geben, falls erforderlich. Ein Dutzend oder so Zeilen von df sind am Ende dieses Beitrags als Referenz.

Hier ist der Code, der die Figur erzeugt:

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) 

Was meine beste Option ist hier die x-Achsenbeschriftungen erhalten zu stoppen einander überlappen (in jeder der vier Nebenhandlungen)? Außerdem, getrennt (aber weniger dringend), was ist mit dem kleinen Tick-Problem im oberen linken Teilplot?

Ich bin auf Pandas 0.13.1, numpy 1.8.0 und Matplotlib 1.4.x.

Hier ist ein kleiner Ausschnitt von df Referenz:

        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: Der Versuch, fig.autofmt_xdate(): Ich glaube nicht, dass dies den Trick tun würde. Dies scheint die gleichen X-Tick-Bezeichnungen für beide Graphen auf der linken Seite und auch für beide Graphen auf der rechten Seite zu verwenden. Was bei meinen Daten nicht stimmt. Bitte beachten Sie die problematische Ausgabe unter:

enter image description here

Antwort

14

Ok, endlich funktioniert es. Der Trick bestand darin, plt.setp zu verwenden, um die Tickbeschriftungen manuell zu drehen. Die Verwendung von fig.autofmt_xdate() funktionierte nicht, da einige unerwartete Dinge passieren, wenn Sie mehrere Unterplots in Ihrer Figur haben. Hier ist der Arbeits Code mit seinem Ausgang:

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

By the way, der Kommentar früher über einige matplotlib Dinge nehmen für immer ist hier sehr interessant. Ich benutze eine Himbeer-Pi, um als Wetterstation an einem abgelegenen Ort zu fungieren. Es sammelt die Daten und liefert die Ergebnisse über das Internet. Und Junge oh Junge, es ist wirklich keuchend zu versuchen, diese Grafiken zu löschen.

7

Aufgrund der Art und Weise Text-Rendering in matplotlib gehandhabt wird, automatische Erkennung überlappenden Text wirklich Dinge verlangsamt. (Der Platz, den der Text in Anspruch nimmt, kann erst nach dem Zeichnen genau berechnet werden.) Aus diesem Grund versucht matplotlib dies nicht automatisch.

Daher ist es am besten, lange Tick-Etiketten zu drehen. Da Daten am häufigsten dieses Problem haben, gibt es eine Zahlenmethode fig.autofmt_xdate(), die (unter anderem) die Hilfsstrichsbeschriftungen drehen wird, um sie ein wenig lesbarer zu machen. (Hinweis: Wenn Sie eine pandas plot Methode verwenden, wird ein Achsenobjekt zurückgegeben. Sie müssen also ax.figure.autofmt_xdate() verwenden.

)

Als kleines Beispiel:

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

Wenn wir fig.autofmt_xdate() auszulassen:

enter image description here

Und wenn wir verwenden fig.autofmt_xdate():

enter image description here

+0

Funktioniert diese Lösung für mehrere Subplots (z. B. ein 2x2-Array) mit unterschiedlichen Datumszeitachsen auf allen? – 8one6

+0

(Ich habe versucht, diese Lösung zu implementieren, aber es werden nur Tickbeschriftungen in der untersten Reihe von Unterplots angezeigt, und diese entsprechen nicht korrekt der obersten Reihe von Unterplots.) – 8one6

Verwandte Themen