简体   繁体   English

使用 Matplotlib 在 3d 中绘制线性模型

[英]Plot linear model in 3d with Matplotlib

I'm trying to create a 3d plot of a linear model fit for a data set.我正在尝试创建适合数据集的线性模型的 3d 图。 I was able to do this relatively easily in R, but I'm really struggling to do the same in Python.我能够在 R 中相对轻松地做到这一点,但我真的很难在 Python 中做到这一点。 Here is what I've done in R:这是我在 R 中所做的:

3d 绘图

Here's what I've done in Python:这是我在 Python 中所做的:

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()

What am I doing wrong and what should I do instead?我做错了什么,我应该怎么做?

Thank you.谢谢你。

Got it!知道了!

The problem that I talk about in the comments to mdurant's answer is that the surface is not plotted as a nice square pattern like these Combining scatter plot with surface plot .我在对 mdurant 的回答的评论中谈到的问题是,表面没有绘制成像这些Combining scatter plot with surface plot那样漂亮的方形图案。

I realized that the problem was my meshgrid , so I corrected both ranges ( x and y ) and used proportional steps for np.arange .我意识到问题出在我的meshgrid ,所以我更正了两个范围( xy )并为np.arange使用了比例步np.arange

This allowed me to use the code provided by mdurant's answer and it worked perfectly!这使我可以使用 mdurant 的答案提供的代码,并且效果很好!

Here's the result:结果如下:

带有 OLS 平面的 3d 散点图

And here's the code:这是代码:

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()

You were correct in assuming that plot_surface wants a meshgrid of coordinates to work with, but predict wants a data structure like the one you fitted with (the "exog").您假设 plot_surface 想要使用坐标网格是正确的,但是 predict 想要一个数据结构,就像您所安装的那样(“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')

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM