如何解决Matplotlib和Pandas对没有周末的时间序列的处理
我在将Matplotlib行添加到Pandas图中时遇到了一些问题。我正在尝试使用斜率绘制一条直线,以确定起点和终点。但是结果图看起来根本不像一条直线。
我将情况简化为下面的MVCE。最初的部分是设置,以复制我拥有的复杂数据框的关键功能。
import pandas as pd
import matplotlib.pyplot as plt
LEN_SER = 23
dates = pd.date_range('2015-07-03',periods=LEN_SER,freq='B')
df = pd.DataFrame(range(1,LEN_SER+1),index=dates)
ts = df.iloc[:,0]
# The above is the setup of the MVCE to replicate the issue.
fig = plt.figure()
ax1 = plt.subplot2grid((1,1),(0,0))
ax1.plot([ts.index[5],ts.index[20]],[ts[5],ts[5] + (1.0 * (20 - 5))],'o-')
ts.plot(ax=ax1)
plt.show()
这给出了一个图表,该图表由于周末而具有波浪线。 Matplotlib正在影响熊猫如何绘制系列。如果我将ax1.plot()线取出,那么它将变成一条直线。
问题是:如何使用Matplotlib在熊猫图上绘制直线?换句话说,我希望绘图将轴标签视为类别,因此周末将被忽略。这样,我希望Matplotlib和Pandas都能给出一条直线。
解决方法
正如您正确观察到的那样,如果删除ax1.plot()行,则matplotlib会将您的日期视为类别,并且pandas图是一条不错的直线。但是,在命令中
ax1.plot([ts.index[5],ts.index[20]],[ts[5],ts[5] + (1.0 * (20 - 5))],'o-')
您要求matplotlib在两点之间进行插值,在插值过程中,matplotlib识别x轴上的日期。这就是为什么关于日期类别(每周5个)的直线熊猫图变成关于日期(每周7个)的波浪线的原因。这也是正确的,因为就日期而言,您的数据根本无法用直线表示。
您可以通过以下方式强制类别解释用字符串替换日期
df.index = df.reset_index().apply(lambda x: x['index'].strftime('%Y-%m-%d'),axis=1)
在定义ts之前。这导致了情节
现在,matplotlib图只是针对两个值的两个类别,并且matplotlib并没有意识到这两个类别都属于熊猫图的类别。 (更改两个图的顺序至少可以节省您的x轴。)将matplotlib图修改为
ax1.plot([5,20],'o-')
在类别5和20之间划一条线,最后给出关于类别x轴的两条直线。
完整代码:
import pandas as pd
import matplotlib.pyplot as plt
plt.style.use('seaborn') # (optional - style was set when I produced my graph)
LEN_SER = 23
dates = pd.date_range('2015-07-03',periods=LEN_SER,freq='B')
df = pd.DataFrame(range(1,LEN_SER+1),index=dates)
df.index = df.reset_index().apply(lambda x: \
x['index'].strftime('%Y-%m-%d'),axis=1) # dates -> categories (string)
ts = df.iloc[:,0]
# The above is the setup of the MVCE to replicate the issue.
fig = plt.figure()
ax1 = plt.subplot2grid((1,1),(0,0))
ax1.plot([5,'o-')
# x coordinates 'categories' 5 and 20
ts.plot(ax=ax1)
plt.show()
,
您已经回答了这个问题:“可能是由于周末”
替换: date = pd.date_range('2015-07-03',period = LEN_SER,freq ='B')
使用
dates = pd.date_range('2015-07-03',freq='D')
B-工作日频率 D-日历频率
并且您的线条变直了。
,您是对的-这是由于周末。您可以通过斜率判断-连续五天的倾斜度(每天+1)比连续三天的倾斜度(总计+1)大。那么,您到底想绘制什么?如果要字面上绘制蓝线,可以像这样在两点之间插入点:
...
# ts.plot(ax=ax1)
ts.iloc[[5,20]].resample('1D').interpolate(how='mean').plot(ax=ax1)
plt.show()
,
为简单起见,我从2015-07- 04 开始。对您有用吗?
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
LEN_SER = 21
dates = pd.date_range('2015-07-04',freq='B')
the_axes = []
# take the_axes like monday and friday for each week
for monday,friday in zip(dates[dates.weekday==0],dates[dates.weekday==4]):
the_axes.append([monday.date(),friday.date()])
x = dates
y = range(1,LEN_SER+1)
n_Axes = len(the_axes)
fig,(axes) = plt.subplots(1,n_Axes,sharey=True,figsize=(15,8))
for i in range(n_Axes):
ax = axes[i]
ax.plot(x,y)
ax.set_xlim(the_axes[i])
fig.autofmt_xdate()
print(dates)
plt.show()
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。