Seaborn tsplot不能很好地在x轴上显示日期时间

sed*_*idw 13 python datetime matplotlib seaborn

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

%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()
Run Code Online (Sandbox Code Playgroud)

结果如下:

在此输入图像描述

正如你所看到的那样,x轴的日期时间有奇怪的数字,而不是常见的"漂亮"表示matplotlib和其他绘图工具.我已经尝试了很多东西,重新格式化数据,但它永远不会干净.有人知道的方法吗?

hit*_*tzg 13

Matplotlib将日期表示为浮点数(以天为单位),因此,除非您(或pandas或seaborn)告诉它您的值表示日期,否则它不会将标记格式化为日期.我不是seaborn专家,但看起来它(或pandas)确实将datetime对象转换为matplotlib日期,但是后来没有为轴指定正确的定位器和格式化程序.这就是为什么你得到这些奇怪的数字,实际上只是自0001.01.01以来的日子.因此,您必须手动处理滴答声(在大多数情况下,它会更好,因为它可以让您获得更多控制).

因此,您必须指定一个日期定位器,它决定放置刻度的位置,以及一个日期格式化程序,然后格式化刻度标签的字符串.

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()
Run Code Online (Sandbox Code Playgroud)

结果:

在此输入图像描述

  • @kurious:我得到了类似的东西:`overflowError:带符号整数大于最大值`来自matfrom来自matfrom -ordinalf(x,tz)的matplotlib/dates.pyc(第214行).用Python 2.7在Linux上安装pip. (6认同)
  • 我收到此错误:OverflowError:Python int太大而无法转换为C long (4认同)

小智 12

对我来说,@ hitzg的答案会在DateFormatter的深度中产生"OverflowError:signed integer is maximum 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))
Run Code Online (Sandbox Code Playgroud)