【问题标题】:How to overplot a line on a scatter plot in python?如何在python中的散点图上绘制一条线?
【发布时间】:2013-10-04 19:40:04
【问题描述】:

我有两个数据向量,我已将它们放入matplotlib.scatter()。现在我想对这些数据进行线性拟合。我该怎么做?我试过使用scikitlearnnp.scatter

【问题讨论】:

    标签: python numpy matplotlib


    【解决方案1】:

    我偏爱scikits.statsmodels。举个例子:

    import statsmodels.api as sm
    import numpy as np
    import matplotlib.pyplot as plt
    
    X = np.random.rand(100)
    Y = X + np.random.rand(100)*0.1
    
    results = sm.OLS(Y,sm.add_constant(X)).fit()
    
    print(results.summary())
    
    plt.scatter(X,Y)
    
    X_plot = np.linspace(0,1,100)
    plt.plot(X_plot, X_plot * results.params[1] + results.params[0])
    
    plt.show()
    

    唯一棘手的部分是sm.add_constant(X),它将一列添加到X 以获得截取项。

         Summary of Regression Results
    =======================================
    | Dependent Variable:            ['y']|
    | Model:                           OLS|
    | Method:                Least Squares|
    | Date:               Sat, 28 Sep 2013|
    | Time:                       09:22:59|
    | # obs:                         100.0|
    | Df residuals:                   98.0|
    | Df model:                        1.0|
    ==============================================================================
    |                   coefficient     std. error    t-statistic          prob. |
    ------------------------------------------------------------------------------
    | x1                      1.007       0.008466       118.9032         0.0000 |
    | const                 0.05165       0.005138        10.0515         0.0000 |
    ==============================================================================
    |                          Models stats                      Residual stats  |
    ------------------------------------------------------------------------------
    | R-squared:                     0.9931   Durbin-Watson:              1.484  |
    | Adjusted R-squared:            0.9930   Omnibus:                    12.16  |
    | F-statistic:                1.414e+04   Prob(Omnibus):           0.002294  |
    | Prob (F-statistic):        9.137e-108   JB:                        0.6818  |
    | Log likelihood:                 223.8   Prob(JB):                  0.7111  |
    | AIC criterion:                 -443.7   Skew:                     -0.2064  |
    | BIC criterion:                 -438.5   Kurtosis:                   2.048  |
    ------------------------------------------------------------------------------
    

    【讨论】:

    • 我的身材看起来不一样了;线路位置错误;以上点
    • @David:参数数组的方向错误。试试:plt.plot(X_plot, X_plot*results.params[1] + results.params[0])。或者,甚至更好: plt.plot(X, results.fittedvalues) 因为第一个公式假设 y 是线性的,所以 x 在这里虽然为真,但并非总是如此。
    【解决方案2】:

    另一种方法,使用axes.get_xlim()

    import matplotlib.pyplot as plt
    import numpy as np
    
    def scatter_plot_with_correlation_line(x, y, graph_filepath):
        '''
        http://stackoverflow.com/a/34571821/395857
        x does not have to be ordered.
        '''
        # Create scatter plot
        plt.scatter(x, y)
    
        # Add correlation line
        axes = plt.gca()
        m, b = np.polyfit(x, y, 1)
        X_plot = np.linspace(axes.get_xlim()[0],axes.get_xlim()[1],100)
        plt.plot(X_plot, m*X_plot + b, '-')
    
        # Save figure
        plt.savefig(graph_filepath, dpi=300, format='png', bbox_inches='tight')
    
    def main():
        # Data
        x = np.random.rand(100)
        y = x + np.random.rand(100)*0.1
    
        # Plot
        scatter_plot_with_correlation_line(x, y, 'scatter_plot.png')
    
    if __name__ == "__main__":
        main()
        #cProfile.run('main()') # if you want to do some profiling
    

    【讨论】:

      【解决方案3】:

      您可以使用 Adarsh Menon 的本教程 https://towardsdatascience.com/linear-regression-in-6-lines-of-python-5e1d0cd05b8d

      这种方式是我找到的最简单的,基本上看起来像:

      import numpy as np
      import matplotlib.pyplot as plt  # To visualize
      import pandas as pd  # To read data
      from sklearn.linear_model import LinearRegression
      data = pd.read_csv('data.csv')  # load data set
      X = data.iloc[:, 0].values.reshape(-1, 1)  # values converts it into a numpy array
      Y = data.iloc[:, 1].values.reshape(-1, 1)  # -1 means that calculate the dimension of rows, but have 1 column
      linear_regressor = LinearRegression()  # create object for the class
      linear_regressor.fit(X, Y)  # perform linear regression
      Y_pred = linear_regressor.predict(X)  # make predictions
      plt.scatter(X, Y)
      plt.plot(X, Y_pred, color='red')
      plt.show()
      

      【讨论】:

        【解决方案4】:
        import numpy as np
        from numpy.polynomial.polynomial import polyfit
        import matplotlib.pyplot as plt
        
        # Sample data
        x = np.arange(10)
        y = 5 * x + 10
        
        # Fit with polyfit
        b, m = polyfit(x, y, 1)
        
        plt.plot(x, y, '.')
        plt.plot(x, b + m * x, '-')
        plt.show()
        

        【讨论】:

        • 你能补充解释吗?
        • polyfit 的第三个参数是度数。全功能签名:numpy.polyfit(x, y, deg, rcond=None, full=False, w=None, cov=False)source
        【解决方案5】:

        用于绘制最佳拟合线的this excellent answer 的单行版本是:

        plt.plot(np.unique(x), np.poly1d(np.polyfit(x, y, 1))(np.unique(x)))
        

        使用np.unique(x) 代替x 处理x 未排序或具有重复值的情况。

        调用poly1d 是写出m*x + b 的替代方法,如this other excellent answer

        【讨论】:

        • 嗨,我的 x 和 y 值是使用 numpy.asarray 从列表转换而来的数组。当我添加这行代码时,我的散点图上有几行而不是一行。可能是什么原因?
        • @artre 感谢您提出这个问题。如果x 未排序或具有重复值,则可能会发生这种情况。我编辑了答案。
        【解决方案6】:

        我喜欢 Seaborn 的 regplotlmplot

        【讨论】:

        • 将 seaborn 导入为 sns; sns.regplot(x=x, y=y)
        【解决方案7】:
        plt.plot(X_plot, X_plot*results.params[0] + results.params[1])
        

        plt.plot(X_plot, X_plot*results.params[1] + results.params[0])
        

        【讨论】:

          猜你喜欢
          • 2021-10-03
          • 2016-03-19
          • 1970-01-01
          • 2022-07-28
          • 1970-01-01
          • 2014-08-30
          • 1970-01-01
          • 2016-03-30
          • 2014-05-13
          相关资源
          最近更新 更多