2014-10-17 85 views
2

我正在嘗試創建適合數據集的線性模型的3D圖。我可以在R中相對容易地做到這一點,但我真的很努力地在Python中做同樣的事情。使用Matplotlib在3D中繪製線性模型

3d plot

這裏就是我在Python進行:以下是我在R來

from mpl_toolkits.mplot3d import Axes3D 
import matplotlib.pyplot as plt 
import numpy as np 
import pandas as pd 
import statsmodels.formula.api as sm 

csv = pd.read_csv('http://www-bcf.usc.edu/~gareth/ISL/Advertising.csv', index_col=0) 
model = sm.ols(formula='Sales ~ TV + Radio', data = csv) 
fit = model.fit() 

fit.summary() 

fig = plt.figure() 
ax = fig.add_subplot(111, projection='3d') 

ax.scatter(csv['TV'], csv['Radio'], csv['Sales'], c='r', marker='o') 

xx, yy = np.meshgrid(csv['TV'], csv['Radio']) 

# Not what I expected :(
# ax.plot_surface(xx, yy, fit.fittedvalues) 

ax.set_xlabel('TV') 
ax.set_ylabel('Radio') 
ax.set_zlabel('Sales') 

plt.show() 

什麼我做錯了,我該怎麼辦呢?

謝謝。

回答

3

假設plot_surface想要一個座標meshgrid可以使用,但是預測需要一個數據結構(如適配的數據結構)(「exog」),那麼您是正確的。

exog = pd.core.frame.DataFrame({'TV':xx.ravel(),'Radio':yy.ravel()}) 
out = fit.predict(exog=exog) 
ax.plot_surface(xx, yy, out.reshape(xx.shape), color='None') 
+1

這類作品,但由此產生的平面非常糟糕繪製。我感到困惑的是,似乎沒有更好更簡單的方法來做到這一點。 – ivanmp 2014-10-17 21:14:53

+0

不好怎麼樣?有許多參數可以提供給plot_surface。如果你想要3D,但你可能想看看mayavi。 – mdurant 2014-10-17 21:25:31

+0

這是http://imgur.com/A5w55U6是我得到的(我刪除了'color ='None')。我正在尋找這樣的東西:http://stackoverflow.com/questions/15229896/matplotlib-3d-plots-combining-scatter-plot-with-surface-plot。順便說一句,感謝您的幫助。 – ivanmp 2014-10-17 21:29:09

5

Got it!

我在mdurant回答的評論中談到的問題是,表面不會被繪製爲像這些Combining scatter plot with surface plot這樣的漂亮方形圖案。

我意識到問題是我meshgrid,所以我糾正兩個範圍(xy)和使用比例步驟np.arange

這讓我可以使用mdurant的答案所提供的代碼,它完美地工作!

這裏的結果:

3d scatter plot with OLS plane

而這裏的代碼:

from mpl_toolkits.mplot3d import Axes3D 
import matplotlib.pyplot as plt 
import numpy as np 
import pandas as pd 
import statsmodels.formula.api as sm 
from matplotlib import cm 

csv = pd.read_csv('http://www-bcf.usc.edu/~gareth/ISL/Advertising.csv', index_col=0) 
model = sm.ols(formula='Sales ~ TV + Radio', data = csv) 
fit = model.fit() 

fit.summary() 

fig = plt.figure() 
ax = fig.add_subplot(111, projection='3d') 

x_surf = np.arange(0, 350, 20)    # generate a mesh 
y_surf = np.arange(0, 60, 4) 
x_surf, y_surf = np.meshgrid(x_surf, y_surf) 

exog = pd.core.frame.DataFrame({'TV': x_surf.ravel(), 'Radio': y_surf.ravel()}) 
out = fit.predict(exog = exog) 
ax.plot_surface(x_surf, y_surf, 
       out.reshape(x_surf.shape), 
       rstride=1, 
       cstride=1, 
       color='None', 
       alpha = 0.4) 

ax.scatter(csv['TV'], csv['Radio'], csv['Sales'], 
      c='blue', 
      marker='o', 
      alpha=1) 

ax.set_xlabel('TV') 
ax.set_ylabel('Radio') 
ax.set_zlabel('Sales') 

plt.show()