【问题标题】:Dotted lines instead of a missing value in matplotlib虚线而不是matplotlib中的缺失值
【发布时间】:2017-07-18 20:35:51
【问题描述】:

我有一些数据的数组,其中一些值丢失了

y = np.array([np.NAN, 45, 23, np.NAN, 5, 14, 22, np.NAN, np.NAN, 18, 23])

当我绘制它时,我缺少这些 NAN(这是预期的)

fig, ax = plt.subplots()
ax.plot(y)
plt.show()

我想要的是连接缺失部分的虚线。例如,在缺少数据点 3 的情况下,应该有一条虚线连接 2 和 4 之间的现有点,(缺少数据点 7 和 8 也是如此。如果数据点位于区间边缘(数据点 0)I希望有一条水平线连接它们(想象上一个/下一个数据点与可用边缘相同)。


saw 这里的问题询问如何删除这些空段(不是我想要的)。我可以通过创建另一个数组来解决它,该数组将插入缺失值和所有其他值 NAN,但它看起来对我来说很复杂。

因为这看起来很常见,我希望有一个更简单的方法。

【问题讨论】:

    标签: python matplotlib


    【解决方案1】:

    我想说链接问题的解决方案可以直接应用在这里,在直线后面画一条虚线。

    import numpy as np
    import matplotlib.pyplot as plt
    
    y = np.array([np.NAN, 45, 23, np.NAN, 5, 14, 22, np.NAN, np.NAN, 18, 23])
    x = np.arange(0, len(y))
    mask = np.isfinite(y)
    
    fig, ax = plt.subplots()
    line, = ax.plot(x[mask],y[mask], ls="--",lw=1)
    ax.plot(x,y, color=line.get_color(), lw=1.5)
    
    plt.show()
    

    为了在边缘值的情况下考虑水平线,可以检查它们是否为 nan 并用相邻值替换它们。

    import numpy as np
    import matplotlib.pyplot as plt
    
    y = np.array([np.NAN, 45, 23, np.NAN, 5, 14, 22, np.NAN, np.NAN, 18, 23,np.NAN])
    x = np.arange(0, len(y))
    yp = np.copy(y)
    if ~np.isfinite(y[0]): yp[0] = yp[1]
    if ~np.isfinite(y[-1]): yp[-1] = yp[-2]
    
    mask = np.isfinite(yp)
    
    
    fig, ax = plt.subplots()
    line, = ax.plot(x[mask],yp[mask], ls="--",lw=1)
    ax.plot(x,y, color=line.get_color(), lw=1.5)
    
    plt.show()
    

    【讨论】:

    • 知道如何处理边缘值吗?
    • 既然边缘没有任何价值,那么如何处理它不是先验的,对吧?所以你需要知道它是否具有某种意义,以及它应该具有什么价值。
    • 在我的问题中,我提到在边缘值的情况下,我希望有一条水平线。基本上如果我有nan, 43,我想有一条虚线43, 43
    • 你是对的,对不起,我错过了那句话。一个解决方案可能是在应用掩码之前首先检查两种可能的情况,如我更新的答案中所示。它不是优雅的,而是工作的。 :-)
    • 非常感谢。这比我打算做的要好得多。
    【解决方案2】:

    您正在寻找的效果的一种快速简单的方法是绘制相同的系列两次,如下所示:

    y = np.array([np.NAN, 45, 23, np.NAN, 5, 14, 22, np.NAN, np.NAN, 18, 23])
    x = np.arange(len(y))
    _y = y[~np.isnan(y)]
    _x = x[~np.isnan(y)]
    fig, ax = plt.subplots()
    
    ax.plot(_x, _y, linestyle="--", lw=.5)
    ax.plot(x, y, lw=1)
    

    请注意,首先绘制连接缺失值的线,然后非缺失值是叠加层(您也可以在调用 plot 中使用zorder kwarg 来控制绘图顺序)。上面的代码创建了这个:

    【讨论】:

    • 知道如何处理边缘值吗?
    • 有很多方法可以处理丢失的边缘数据,具体取决于您要显示的内容。通常我会说应该删除前面的nan 值,但是如果您使用nan 来指示有用的数据,例如化学分析时间序列中的未检测,那么我考虑使用填充的散点图nan 值与分析方法检测限。您填写缺失数据的原因可能会有所不同,但是一旦您选择了一种方法(和一个原因),如果您需要有关使用matplotlib 以按照您的设想进行绘制的帮助,您可以提出另一个问题。
    【解决方案3】:

    这是一个在边缘使用多个 NaN 的解决方案。为了证明这一点,我在每一侧添加了一个 NaN。

    import numpy as np
    import matplotlib.pyplot as plt
    
    y = np.array([np.NAN, np.NAN, 45, 23, np.NAN, 5, 14, 22, np.NAN, np.NAN, 18, 23, np.NAN])
    x = np.arange(0, len(y))
    
    mask = np.isfinite(y)
    
    # get first value in list
    for i in range(len(mask)):
        if mask[i]:
            first = i
            break
    
    # get last vaue in list
    for i in range(len(mask)-1, -1, -1):
        if mask[i]:
            last = i
            break
    
    # fill NaN with near known value on the edges
    yp = np.copy(y)
    yp[:first] = yp[first]
    yp[last + 1:] = yp[last]
    
    mask = np.isfinite(yp)
    
    fig, ax = plt.subplots()
    line, = ax.plot(x[mask],yp[mask], ls="--",lw=1)
    ax.plot(x,y, color=line.get_color(), lw=1.5)
    
    plt.show()
    

    可以使用numpy.where,以减少代码,但在这里简单的python 迭代实际上更有效。查看比较in my comment here

    ind = np.where(y)[0]
    first, last = ind[0], ind[-1]
    

    【讨论】:

      猜你喜欢
      • 2015-05-23
      • 2016-09-11
      • 2020-08-12
      • 1970-01-01
      • 2016-11-26
      • 2021-02-23
      • 1970-01-01
      • 2021-04-20
      • 2021-08-05
      相关资源
      最近更新 更多