代码之家  ›  专栏  ›  技术社区  ›  user3789200

Matplotlib:平滑折线图[重复]

  •  0
  • user3789200  · 技术社区  · 5 年前

    我有以下简单的脚本来绘制一个图:

    import matplotlib.pyplot as plt
    import numpy as np
    
    T = np.array([6, 7, 8, 9, 10, 11, 12])
    power = np.array([1.53E+03, 5.92E+02, 2.04E+02, 7.24E+01, 2.72E+01, 1.10E+01, 4.70E+00])
    
    plt.plot(T,power)
    plt.show()
    

    smooth cplines .

    在PyPlot中有没有一种简单的方法可以做到这一点?我找到了一些教程,但看起来都很复杂。

    0 回复  |  直到 4 年前
        1
  •  183
  •   brezniczky    5 年前

    你可以用 scipy.interpolate.spline 要自己平滑数据:

    from scipy.interpolate import spline
    
    # 300 represents number of points to make between T.min and T.max
    xnew = np.linspace(T.min(), T.max(), 300)  
    
    power_smooth = spline(T, power, xnew)
    
    plt.plot(xnew,power_smooth)
    plt.show()
    

    正在从切换 spline BSpline 不是简单的复制/粘贴,需要稍加调整:

    from scipy.interpolate import make_interp_spline, BSpline
    
    # 300 represents number of points to make between T.min and T.max
    xnew = np.linspace(T.min(), T.max(), 300) 
    
    spl = make_interp_spline(T, power, k=3)  # type: BSpline
    power_smooth = spl(xnew)
    
    plt.plot(xnew, power_smooth)
    plt.show()
    

    之前: screenshot 1

    screenshot 2

        2
  •  35
  •   Sajad Norouzi    5 年前

    对于本例,样条曲线工作良好,但如果函数本身不是平滑的,并且您希望具有平滑的版本,则也可以尝试:

    from scipy.ndimage.filters import gaussian_filter1d
    
    ysmoothed = gaussian_filter1d(y, sigma=2)
    plt.plot(x, ysmoothed)
    plt.show()
    

    如果你增加sigma,你可以得到一个更平滑的函数。

    小心处理这个。它会修改原始值,可能不是您想要的。

        3
  •  9
  •   Nick Bastin    13 年前

    我想你是说 curve-fitting 而不是 anti-aliasing 从你问题的背景来看。PyPlot对此没有任何内置支持,但是您可以轻松地实现一些基本的曲线拟合,就像前面看到的代码一样 here ,或者如果您使用的是GuiQwt,它有一个曲线拟合 module SciPy

        4
  •  6
  •   Mateen Ulhaq    3 年前

    看到了吗 scipy.interpolate

    下面的示例演示了它在线性和三次样条插值中的用法:

    import matplotlib.pyplot as plt
    import numpy as np
    from scipy.interpolate import interp1d
    
    # Define x, y, and xnew to resample at.
    x = np.linspace(0, 10, num=11, endpoint=True)
    y = np.cos(-x**2/9.0)
    xnew = np.linspace(0, 10, num=41, endpoint=True)
    
    # Define interpolators.
    f_linear = interp1d(x, y)
    f_cubic = interp1d(x, y, kind='cubic')
    
    # Plot.
    plt.plot(x, y, 'o', label='data')
    plt.plot(xnew, f_linear(xnew), '-', label='linear')
    plt.plot(xnew, f_cubic(xnew), '--', label='cubic')
    plt.legend(loc='best')
    plt.show()
    

    enter image description here

    为增加可读性而略微修改。

        5
  •  5
  •   tobias88    4 年前

    from scipy.interpolate import make_interp_spline
    import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib.dates as dates
    from datetime import datetime
    
    data = {
        datetime(2016, 9, 26, 0, 0): 26060, datetime(2016, 9, 27, 0, 0): 23243,
        datetime(2016, 9, 28, 0, 0): 22534, datetime(2016, 9, 29, 0, 0): 22841,
        datetime(2016, 9, 30, 0, 0): 22441, datetime(2016, 10, 1, 0, 0): 23248 
    }
    #create data
    date_np = np.array(list(data.keys()))
    value_np = np.array(list(data.values()))
    date_num = dates.date2num(date_np)
    # smooth
    date_num_smooth = np.linspace(date_num.min(), date_num.max(), 100) 
    spl = make_interp_spline(date_num, value_np, k=3)
    value_np_smooth = spl(date_num_smooth)
    # print
    plt.plot(date_np, value_np)
    plt.plot(dates.num2date(date_num_smooth), value_np_smooth)
    plt.show()
    

    example

        6
  •  1
  •   Charly Empereur-mot    3 年前

    另一种方法是根据您使用的参数对函数进行轻微修改:

    from statsmodels.nonparametric.smoothers_lowess import lowess
    
    def smoothing(x, y):
        lowess_frac = 0.15  # size of data (%) for estimation =~ smoothing window
        lowess_it = 0
        x_smooth = x
        y_smooth = lowess(y, x, is_sorted=False, frac=lowess_frac, it=lowess_it, return_sorted=False)
        return x_smooth, y_smooth