我的DataFrame对象看起来像
amount
date
2014-01-06 1
2014-01-07 1
2014-01-08 4
2014-01-09 1
2014-01-14 1
我想要一种沿着x轴的时间散点图,以及y上的数量,用数据线来引导观察者的眼睛。如果我使用panadas情节df.plot(style="o")
它不太正确,因为线路不在那里。我希望像here这样的例子。
答案 0 :(得分:5)
注意:这与Ian Thompson的答案有很多共同之处,但这种方法不同,足以让它成为一个单独的答案。我使用问题中提供的DataFrame格式,并避免更改索引。
Seaborn和其他图书馆也不像你希望的那样处理日期时间轴。以下是我如何解决这个问题的方法:
Seaborn将更好地处理这些而不是日期。这是一个方便的伎俩,可以用日期和图书馆来做各种各样的蠢事。不喜欢约会。
df['date_ordinal'] = pd.to_datetime(df['date']).apply(lambda date: date.toordinal())
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)
ax.set_xlabel('date')
new_labels = [date.fromordinal(int(item)) for item in ax.get_xticks()]
ax.set_xticklabels(new_labels)
TA-DAA!
答案 1 :(得分:2)
由于Seaborn对日期有困难,我将创建一个解决方案。 首先,我将Date列作为索引:
# 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'])
其次,将索引转换为pd.DatetimeIndex:
# Make index pd.DatetimeIndex
df.index = pd.DatetimeIndex(df.index)
用它替换原件:
# Make new index
idx = pd.date_range(df.index.min(), df.index.max())
第三,使用新索引(idx)重新索引:
# Replace original index with idx
df = df.reindex(index = idx)
这将生成一个新数据框,其中包含您没有数据的日期的NaN值:
第四,由于Seaborn对日期和回归线不起作用,我将创建一个行计数列,我们可以将其用作x轴:
# Insert row count
df.insert(df.shape[1],
'row_count',
df.index.value_counts().sort_index().cumsum())
第五,我们现在应该能够使用'row_count'作为我们的x变量和'amount'作为我们的y变量来绘制回归线:
# Plot regression using Seaborn
fig = sns.regplot(data = df, x = 'row_count', y = 'amount')
第六,如果您希望日期沿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();
希望这有帮助!