Seaborn tsplot不在x轴上显示日期时间

2024-04-28 21:32:34 发布

您现在位置:Python中文网/ 问答频道 /正文

下面的脚本创建了一个简单的时间序列图:

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

其结果如下:

enter image description here

正如您所看到的,x轴对于日期时间有奇怪的数字,而不是通常的matplotlib和其他绘图实用程序附带的“好”表示。我试过很多方法,重新格式化数据,但结果总是不干净。有人知道怎么走吗?


Tags: importdffordatetimedatematplotlibas时间
3条回答

这是一个潜在的不雅的解决方案,但它是唯一一个我有。。。希望有帮助!

    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');

如果你看到任何问题,请告诉我!

Matplotlib将日期表示为浮点数(以天为单位),因此,除非您(或pandas或seaborn)告诉它您的值表示日期,否则它不会将刻度设置为日期格式。我不是一个天生的专家,但是看起来它(或者熊猫)确实将datetime对象转换为matplotlib日期,但是没有为轴分配适当的定位器和格式化程序。这就是为什么你会得到这些奇怪的数字,事实上,它们只是0001.01.01之后的几天。因此,您必须手动处理滴答声(在大多数情况下,这是更好的,因为它给您更多的控制)。

因此,您必须指定一个date locator,决定在哪里放置记号,以及一个date formatter,然后为记号标签格式化字符串。

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

结果:

enter image description here

对我来说,@hitzg的回答会导致DateFormatter深处出现“OverflowError:signed integer is greater than maximum”。

看看我的数据帧,我的索引是datetime64,而不是datetime。但是熊猫很好地转换了这些。以下对我很有用:

import matplotlib as mpl

def myFormatter(x, pos):
    return pd.to_datetime(x)

[ . . . ]

ax.xaxis.set_major_formatter(mpl.ticker.FuncFormatter(myFormatter))

相关问题 更多 >