2016-06-23 12 views
0

Ich möchte eine Reihe von Werten für einen Datumsbereich in Matplotlib plotten. Ich habe den Tick base Parameter zu 7 geändert, um einen Tick zu Beginn jeder Woche zu erhalten (plticker.IndexLocator, base = 7). Das Problem ist, dass die set_xticklabels Funktion einen base Parameter nicht akzeptiert. Daher ist der zweite Tick (der Tag 8 am Anfang der zweiten Woche) mit Tag 2 aus meiner Datumsbereichsliste markiert und nicht mit Tag 8, wie er sein sollte (siehe Bild).Matplotlib: So erhalten Sie die gleichen "Basis" - und "Offset" -Parameter für Achsen-Ticks und Achsen-Tick-Labels

Wie geben Sie set_xticklabels einen base Parameter?

Hier ist der Code:

my_data = pd.read_csv("%r_filename_%s_%s_%d_%d.csv" % (num1, num2, num3, num4, num5), dayfirst=True) 
my_data.plot(ax=ax1, color='r', lw=2.) 
loc = plticker.IndexLocator(base=7, offset = 0) # this locator puts ticks at regular intervals 
ax1.set_xticklabels(my_data.Date, rotation=45, rotation_mode='anchor', ha='right') # this defines the tick labels 
ax1.xaxis.set_major_locator(loc) 

ist die Handlung:

Plot

Antwort

0

Der Grund Ihrer ticklabels schlecht ging, dass setting manual ticklabels decouples the labels from your data. Der richtige Ansatz besteht darin, einen Formatter entsprechend Ihren Bedürfnissen zu verwenden. Da Sie für jeden Datenpunkt eine Liste von Ticklabels haben, können Sie eine IndexFormatter verwenden. Es scheint, Online-undokumentiert werden, aber es hat eine Hilfe:

class IndexFormatter(Formatter) 
| format the position x to the nearest i-th label where i=int(x+0.5) 
| ... 
| __init__(self, labels) 
| ... 

So müssen Sie nur Ihre Liste der Daten zu IndexFormatter geben. Mit einem minimalen, Pandas unabhängigem Beispiel (mit numpy nur zum Erzeugen von Dummy-Daten):

import numpy as np 
import matplotlib.pyplot as plt 
import matplotlib as mpl 


# create dummy data  
x = ['str{}'.format(k) for k in range(20)] 
y = np.random.rand(len(x)) 

# create an IndexFormatter with labels x 
x_fmt = mpl.ticker.IndexFormatter(x) 

fig,ax = plt.subplots() 
ax.plot(y) 
# set our IndexFormatter to be responsible for major ticks 
ax.xaxis.set_major_formatter(x_fmt) 

Dies sollte Ihre Daten und Etiketten gepaart halten, auch wenn tick Positionen ändern:

result

Ich bemerkte, Sie setzen auch die Rotation der Ticklabels im Aufruf auf set_xticklabels, Sie würden dies jetzt verlieren. Ich schlage vor, stattdessen fig.autofmt_xdate zu verwenden, scheint es genau für diesen Zweck entworfen zu werden, ohne mit Ihren Ticklabel-Daten zu verwirren.

0

Vielen Dank - Ihre Lösung funktioniert perfekt. Für den Fall, dass andere Leute in Zukunft auf dasselbe Problem stoßen: Ich habe die oben erwähnte Lösung implementiert, aber auch etwas Code hinzugefügt, so dass die Tick-Labels die gewünschte Rotation beibehalten und sich (mit ihrem linken Ende) an dem jeweiligen Tick ausrichten . Kann nicht Python, möglicherweise nicht Best-Practice, aber es funktioniert

x_fmt = mpl.ticker.IndexFormatter(x) 
ax.set_xticklabels(my_data.Date, rotation=-45) 
ax.tick_params(axis='x', pad=10) 
ax.xaxis.set_major_formatter(x_fmt) 
labels = my_data.Date 
for tick in ax.xaxis.get_majorticklabels(): 
    tick.set_horizontalalignment("left")