I'm trying to create a 3d plot of a linear model fit for a data set. I was able to do this relatively easily in R, but I'm really struggling to do the same in Python. Here is what I've done in R:
Here's what I've done in 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.
I realized that the problem was my
meshgrid
, so I corrected both ranges (x
andy
) and used proportional steps fornp.arange
.This allowed me to use the code provided by mdurant's answer and it worked perfectly!
Here's the result:
And here's the code:
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").