Let's start from the beginning. This how I getting x
and y
values:
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = fig.gca(projection='3d') # get current axis
w0 = np.arange(30, 80, 1) # x - values
w1 = np.arange(-3, 3, 0.1) # y - values
X, Y = np.meshgrid(w0, w1) # no idea why to do that
Because I don't know how to avoid loops I go this way to calculate Z values:
sizeWo = len(w0)
sizeW1 = len(w1)
Z = np.zeros((sizeWo, sizeW1))
for i in xrange(0,sizeWo):
for j in xrange(0,sizeW1):
Z[i,j] = errorLose(w0[i], w1[j])
surf = ax.plot_surface(X, Y, Z) # that lines generates the error (ValueError: shape mismatch: objects cannot be broadcast to a single shape)
Even this code generates the same error:
surf = ax.plot_surface(w0, w1, Z) shape mismatch: objects cannot be broadcast to a single shape
plt.show()
What is wrong here and how to make it work?
errorLose
function takes two values and calculates error using dataframe data
behind:
def errorLose(w0,w1):
return np.sum((data.Height - (w0 + w1 *data.Weight))**2)
This is how you can get the same data. This the link to the csv file:
data = pd.read_csv('weights_heights.csv', index_col='Index')
You're very close. The issue is that you are creating Z
to be sizeWo x sizeW1
but meshgrid
creates X
and Y
which are size sizeW1 x sizeW0
. You can either setup Z
differently:
Z = np.zeros((sizeW1, sizeWo))
for i in xrange(0,sizeWo):
for j in xrange(0,sizeW1):
Z[j,i] = errorLose(w0[i], w1[j])
Or you could keep Z
the same and simply pass the transpose of Z
to your plot constructor
surf = ax.plot_surface(X, Y, np.transpose(Z))
Update
The reason that you need to use meshgrid
is that your x and y coordinates are only 1D arrays initially and plot_surface
expects X
and Y
to be 2D arrays. What meshgrid
does is it creates 2D arrays from the two inputs with every permutation of the two. This answer contains a more detailed discussion of meshgrid
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With