matplotlib:在忽略缺失数据的点之间绘制线条

gra*_*age 53 python matplotlib

我有一组数据,我想绘制为线图.对于每个系列,缺少一些数据(但每个系列都不同).目前,matplotlib不会绘制跳过缺失数据的行:例如

import matplotlib.pyplot as plt

xs = range(8)
series1 = [1, 3, 3, None, None, 5, 8, 9]
series2 = [2, None, 5, None, 4, None, 3, 2]

plt.plot(xs, series1, linestyle='-', marker='o')
plt.plot(xs, series2, linestyle='-', marker='o')

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

导致线条中有间隙的图.如何告诉matplotlib在间隙中绘制线条?(我宁愿不必插入数据).

Tho*_*anz 74

您可以通过以下方式屏蔽NaN值:

import numpy as np
import matplotlib.pyplot as plt

xs = np.arange(8)
series1 = np.array([1, 3, 3, None, None, 5, 8, 9]).astype(np.double)
s1mask = np.isfinite(series1)
series2 = np.array([2, None, 5, None, 4, None, 3, 2]).astype(np.double)
s2mask = np.isfinite(series2)

plt.plot(xs[s1mask], series1[s1mask], linestyle='-', marker='o')
plt.plot(xs[s2mask], series2[s2mask], linestyle='-', marker='o')

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

这导致

情节


Mar*_*hke 6

熊猫的解决方案:

import matplotlib.pyplot as plt
import pandas as pd

def splitSerToArr(ser):
    return [ser.index, ser.as_matrix()]


xs = range(8)
series1 = [1, 3, 3, None, None, 5, 8, 9]
series2 = [2, None, 5, None, 4, None, 3, 2]

s1 = pd.Series(series1, index=xs)
s2 = pd.Series(series2, index=xs)

plt.plot( *splitSerToArr(s1.dropna()), linestyle='-', marker='o')
plt.plot( *splitSerToArr(s2.dropna()), linestyle='-', marker='o')

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

splitSerToArr在 Pandas 中绘图时,该功能非常方便。这是输出:在此处输入图片说明

  • 有什么方法可以用 DataFrame 实现这一点吗?和/或使用 pandas 的 `.plot()`? (2认同)

Nas*_*ibi 5

Qouting @罗格·卡西斯(链接):

Matplotlib仅在连续的(有效)数据点之间绘制一条线,并在NaN值之间留出间隙。

如果您使用的是熊猫的解决方案,:

#pd.Series 
s.dropna().plot() #masking (as @Thorsten Kranz suggestion)

#pd.DataFrame
df['a_col_ffill'] = df['a_col'].ffill(method='ffill')
df['b_col_ffill'] = df['b_col'].ffill(method='ffill')  # changed from a to b
df[['a_col_ffill','b_col_ffill']].plot()
Run Code Online (Sandbox Code Playgroud)

  • 如果 NaN 值位于不同列中的不同位置,则第一个建议根本不起作用,如 OP 的问题。第二个建议与 OP 预期的行为完全不同。a) 它用系列中的前一个值填充 NaN 值,这会扭曲曲线。如果您进行插值,则不会发生这种情况。b) 如果您像在 OP 的代码中那样绘制标记,您将获得数据中实际为 NaN 的点的标记。 (4认同)
  • 供将来参考:它应该是`df.ffill()` 或`df.fillna(method='ffill')`(至少在pandas 0.17+ 上) (3认同)