在pyplot线图中设置间隙/中断而不会丢失数据

时间:2018-03-27 21:27:10

标签: python numpy matplotlib

我有一个包含几个大数据空白的时间序列。我希望看到数据点之间的连接线相隔不到一小时,但如果间隙较大则不行。问题的接受答案Put a gap/break in a line plot将起作用,除了你牺牲蒙面的点数。我想避免这种情况。

我试图制作一个将NaN插入数组的列表理解,我认为这会自动实现相同的结果,但我似乎无法正确地做到这一点。我发现的最好的如下:

import datetime as dtm
import numpy    as np

x = np.array([dtm.datetime(2001,4,3,0,47,30),dtm.datetime(2001,4,3,0,52,30),dtm.datetime(2001,4,3,0,57,30),dtm.datetime(2001,4,3,3,57,30),dtm.datetime(2001,4,3,4,2,30),dtm.datetime(2001,4,3,4,7,30)])

xmod = np.array([x[0]]+[dt1 if dt1-dt0 < dtm.timedelta(hours=1.) else [dt1,np.nan] for dt1, dt0 in zip(x[1:],x[:-1])])

这给出了结果:

In [7]: xmod
Out[7]: 
   array([datetime.datetime(2001, 4, 3, 0, 47, 30),
   datetime.datetime(2001, 4, 3, 0, 47, 30),
   datetime.datetime(2001, 4, 3, 0, 52, 30),
   [datetime.datetime(2001, 4, 3, 0, 57, 30), nan],
   datetime.datetime(2001, 4, 3, 3, 57, 30),
   datetime.datetime(2001, 4, 3, 4, 2, 30)], dtype=object)

我没有找到一种方法来插入数据点和np.nan而不在它们周围放置括号。这可能吗?有没有更好的方法来实现我的目标?谢谢!

2 个答案:

答案 0 :(得分:1)

根据上面的评论,最简单的方法可能是将数据分成需要差距的组。这是实现这种事情的一种方法。

import datetime as dtm
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

x = np.array([dtm.datetime(2001,4,3,0,47,30),dtm.datetime(2001,4,3,0,52,30),dtm.datetime(2001,4,3,0,57,30),
              dtm.datetime(2001,4,3,3,57,30),dtm.datetime(2001,4,3,4,2,30),dtm.datetime(2001,4,3,4,7,30)])

y = range(len(x))

# make a dataframe with groups separated that are over an hour apart
data = []
g = 0
for i in range(len(x)):
    x0 = x[i]
    y0 = y[i]
    if i < (len(x)-1):
        x1 = x[i+1]
        td = x1 - x0
        elapsed_seconds = td.total_seconds()
        hrs = (elapsed_seconds/60)/60
        if hrs < 1:
            data.append([x0,y0, g])
        else:
            data.append([x0,y0, g])
            g+=1
    else:
        data.append([x0,y0, g])

df = pd.DataFrame(data, columns=['x', 'y', 'group'])

# draw a plot
fig, ax = plt.subplots(1,1, figsize = (8,5))
for i, dfg in df.groupby('group'):

    ax.plot(dfg['x'], dfg['y'], c='b')

enter image description here

答案 1 :(得分:0)

所以,我接受了djakubosky的答案,因为它似乎很干净,可能是正确的方法。然而,到答案发布时,我已经决定我正在做的事情不适合列表理解,只是把它写成for循环 - 这很好。可能这对其他人有用。这是代码:

 Dim request As WebRequest = WebRequest .Create(“myserver.com/post.php?w=“ & Textbox1.Text)