我可以在Seaborn的x轴上绘制日期时间的线性回归吗?

the*_*man 8 python matplotlib dataframe pandas seaborn

我的DataFrame对象看起来像

            amount
date    
2014-01-06  1
2014-01-07  1
2014-01-08  4
2014-01-09  1
2014-01-14  1
Run Code Online (Sandbox Code Playgroud)

我想要一种散布图,其中沿x轴的时间为时间,沿y的量为时间,并通过数据线来引导观察者的眼睛。如果我使用panadas图,df.plot(style="o")那是不太正确的,因为那条线不在那。我想要类似这里的示例。

wat*_*oof 9

注意:这与Ian Thompson的答案有很多共同点,但是方法不同,足以将其作为单独的答案。我使用问题中提供的DataFrame格式,并避免更改索引。

Seaborn和其他图书馆对日期时间轴的处理不尽如人意。这是我的解决方法:

首先添加一列日期序号

与日期相比,Seaborn将更好地处理这些问题。这对于使用日期和不喜欢日期的库进行各种数学运算是一个方便的技巧。

df['date_ordinal'] = pd.to_datetime(df['date']).apply(lambda date: date.toordinal())
Run Code Online (Sandbox Code Playgroud)

普通数据框

在日期轴上使用序数进行绘图

ax = seaborn.regplot(
    data=df,
    x='date_ordinal',
    y='amount',
)
# Tighten up the axes for prettiness
ax.set_xlim(df['date_ordinal'].min() - 1, df['date_ordinal'].max() + 1)
ax.set_ylim(0, df['amount'].max() + 1)
Run Code Online (Sandbox Code Playgroud)

用好看的日期替换顺序的X轴标签

ax.set_xlabel('date')
new_labels = [date.fromordinal(int(item)) for item in ax.get_xticks()]
ax.set_xticklabels(new_labels)
Run Code Online (Sandbox Code Playgroud)

用回归线绘图

ta-daa!


Ian*_*son 3

由于 Seaborn 在处理日期方面遇到问题,我将创建一个解决方法。首先,我将把日期列作为我的索引:

# Make dataframe
df = pd.DataFrame({'amount' : [1,
                               1,
                               4,
                               1,
                               1]},
                  index = ['2014-01-06',
                           '2014-01-07',
                           '2014-01-08',
                           '2014-01-09',
                           '2014-01-14'])
Run Code Online (Sandbox Code Playgroud)

其次,将索引转换为 pd.DatetimeIndex:

# Make index pd.DatetimeIndex
df.index = pd.DatetimeIndex(df.index)
Run Code Online (Sandbox Code Playgroud)

并用它替换原来的:

# Make new index
idx = pd.date_range(df.index.min(), df.index.max())
Run Code Online (Sandbox Code Playgroud)

第三,使用新索引(idx)重新索引:

# Replace original index with idx
df = df.reindex(index = idx)
Run Code Online (Sandbox Code Playgroud)

这将生成一个新的数据框,其中包含您没有数据的日期的 NaN 值:

df编辑

第四,由于 Seaborn 不能很好地处理日期和回归线,我将创建一个行计数列,我们可以将其用作 x 轴:

# Insert row count
df.insert(df.shape[1],
          'row_count',
          df.index.value_counts().sort_index().cumsum())
Run Code Online (Sandbox Code Playgroud)

第五,我们现在应该能够使用“row_count”作为 x 变量和“amount”作为 y 变量来绘制回归线:

# Plot regression using Seaborn
fig = sns.regplot(data = df, x = 'row_count', y = 'amount')
Run Code Online (Sandbox Code Playgroud)

第六,如果您希望日期沿着 x 轴而不是 row_count,您可以将 x-tick 标签设置为索引:

# Change x-ticks to dates
labels = [item.get_text() for item in fig.get_xticklabels()]

# Set labels for 1:10 because labels has 11 elements (0 is the left edge, 11 is the right
# edge) but our data only has 9 elements
labels[1:10] = df.index.date

# Set x-tick labels
fig.set_xticklabels(labels)

# Rotate the labels so you can read them
plt.xticks(rotation = 45)

# Change x-axis title
plt.xlabel('date')

plt.show();
Run Code Online (Sandbox Code Playgroud)

剧情编辑2

希望这可以帮助!