matplotlib:在点之间画线,忽略丢失的数据
我有一组数据,我想绘制为一个线图。 对于每个系列,缺less一些数据(但是每个系列都不相同)。 目前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()
导致线路中存在空白的情节。 我怎么能告诉matplotlib通过差距画线? (我宁愿不必插入数据)。
你可以这样掩盖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()
这导致
Qouting @Rutger Kassies( 链接 ):
Matplotlib只在连续的(有效的)数据点之间绘制一条线,并在NaN值处留下间隙。
一个解决scheme,如果你使用pandas ,
#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()
没有插值,你需要从数据中删除None。 这也意味着您需要删除系列中与“无”对应的X值。 这是一个(丑)一个class轮做这件事:
x1Clean,series1Clean = zip(* filter( lambda x: x[1] is not None , zip(xs,series1) ))
lambda函数为None值返回False,从列表中过滤x,series对,然后将数据重新压缩为原始forms。
经过一番反复试验,我想补充一下Thorsten的解决scheme。 希望在尝试这种方法之后为在别处寻找的用户节省时间。
在使用时,我无法获得成功
from pyplot import *
并试图与阴谋
plot(abscissa[mask],ordinate[mask])
它似乎需要使用import matplotlib.pyplot as plt
来获得正确的NaNs处理,虽然我不能说为什么。
也许我错过了这一点,但我相信pandas现在自动做到这一点 。 下面的例子有点牵扯,需要上网,但是中国的路线早年有很多的空白,因此是直线段。
import pandas as pd import numpy as np import matplotlib.pyplot as plt # read data from Maddison project url = 'http://www.ggdc.net/maddison/maddison-project/data/mpd_2013-01.xlsx' mpd = pd.read_excel(url, skiprows=2, index_col=0, na_values=[' ']) mpd.columns = map(str.rstrip, mpd.columns) # select countries countries = ['England/GB/UK', 'USA', 'Japan', 'China', 'India', 'Argentina'] mpd = mpd[countries].dropna() mpd = mpd.rename(columns={'England/GB/UK': 'UK'}) mpd = np.log(mpd)/np.log(2) # convert to log2 # plots ax = mpd.plot(lw=2) ax.set_title('GDP per person', fontsize=14, loc='left') ax.set_ylabel('GDP Per Capita (1990 USD, log2 scale)') ax.legend(loc='upper left', fontsize=10, handlelength=2, labelspacing=0.15) fig = ax.get_figure() fig.show()