Nachfolgend habe ich das folgende Skript, das eine einfache Zeitreihendarstellung erstellt:
%matplotlib inline
import datetime
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
df = []
start_date = datetime.datetime(2015, 7, 1)
for i in range(10):
for j in [1,2]:
unit = 'Ones' if j == 1 else 'Twos'
date = start_date + datetime.timedelta(days=i)
df.append({
'Date': date.strftime('%Y%m%d'),
'Value': i * j,
'Unit': unit
})
df = pd.DataFrame(df)
sns.tsplot(df, time='Date', value='Value', unit='Unit', ax=ax)
fig.autofmt_xdate()
Und das Ergebnis davon ist folgendes:
Wie Sie sehen, hat die x-Achse merkwürdige Zahlen für die Datumszeit und nicht die üblichen "Nice" -Darstellungen, die mit matplotlib
und anderen Plot-Dienstprogrammen geliefert werden. Ich habe viele Dinge ausprobiert, die Daten neu formatiert, aber sie kommen nie sauber heraus. Wer kennt sich aus?
Matplotlib stellt Datumsangaben als Gleitkommazahlen dar (in Tagen). Wenn Sie (oder Pandas oder Seaborns) nicht sagen, dass Ihre Werte Datumsangaben darstellen, werden die Ticks nicht als Datumsangaben formatiert. Ich bin kein Seaborn-Experte, aber es sieht so aus, als würde er (oder Pandas) die datetime
-Objekte in matplotlib-Datumsangaben konvertieren, ordnet dann aber den Achsen keine richtigen Locators und Formatierer zu. Deshalb erhalten Sie diese seltsamen Zahlen, die eigentlich nur die Tage seit 0001.01.01 sind. Sie müssen sich also manuell um die Ticks kümmern (was in den meisten Fällen besser ist, da Sie mehr Kontrolle haben).
Sie müssen also einen date locator zuweisen, der entscheidet, wohin Ticks gesetzt werden sollen, und ein date formatatter , das dann die Zeichenfolgen für die Tick-Labels formatiert.
import datetime
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
# build up the data
df = []
start_date = datetime.datetime(2015, 7, 1)
for i in range(10):
for j in [1,2]:
unit = 'Ones' if j == 1 else 'Twos'
date = start_date + datetime.timedelta(days=i)
# I believe it makes more sense to directly convert the datetime to a
# "matplotlib"-date (float), instead of creating strings and then let
# pandas parse the string again
df.append({
'Date': mdates.date2num(date),
'Value': i * j,
'Unit': unit
})
df = pd.DataFrame(df)
# build the figure
fig, ax = plt.subplots()
sns.tsplot(df, time='Date', value='Value', unit='Unit', ax=ax)
# assign locator and formatter for the xaxis ticks.
ax.xaxis.set_major_locator(mdates.AutoDateLocator())
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y.%m.%d'))
# put the labels at 45deg since they tend to be too long
fig.autofmt_xdate()
plt.show()
Ergebnis:
Für mich führt die Antwort von @ hitzg in den Tiefen von DateFormatter zu "OverflowError: Vorzeichenlose Ganzzahl ist größer als das Maximum".
Wenn ich meinen Datenrahmen betrachte, sind meine Indizes datetime64 und nicht datetime. Pandas konvertieren diese jedoch gut. Folgendes funktioniert für mich großartig:
import matplotlib as mpl
def myFormatter(x, pos):
return pd.to_datetime(x)
[ . . . ]
ax.xaxis.set_major_formatter(mpl.ticker.FuncFormatter(myFormatter))
Hier ist eine potenziell inelegante Lösung, aber es ist die einzige, die ich habe ... Hoffe, es hilft!
g = sns.pointplot(x, y, data=df, ci=False);
unique_dates = sorted(list(df['Date'].drop_duplicates()))
date_ticks = range(0, len(unique_dates), 5)
g.set_xticks(date_ticks);
g.set_xticklabels([unique_dates[i].strftime('%d %b') for i in date_ticks], rotation='vertical');
g.set_xlabel('Date');
Lassen Sie mich wissen, wenn Sie Probleme sehen!
def myFormatter(x, pos):
return pd.to_datetime(x).strftime('%Y%m%d')
ax.xaxis.set_major_formatter(mpl.ticker.FuncFormatter(myFormatter))