3

I have a question quite similar to this one Matplotlib 3D plot - 2D format for input data? but it only partly solved my problem (which was originally that .plot_surface() didn't recognize any arguments). What I am trying to do is plot a function of 2 parameters and this is what I have:

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
X,Y = np.meshgrid(positions[0],np.transpose(positions[1]))
Z = data[0]
Axes3D.plot_surface(X, Y, Z)

which throws this error:

TypeError: plot_surface() missing 1 required positional argument: 'Z'

data[0] is a 2D array. (data is a list of 2D arrays). positions is a tuple of a row vector and a column vector, so line 3 is essentially reconstructing positions as two row vectors and then making two matrices one for X and one for Y values as I believe Axes3D.plot_surface() requires.

My problem is that even though Z is 2D array, .plot_surface() refuses to recognize it as such.

Edit: I just confirmed that Z is indeed the correct shape using this:

if Z.shape == X.shape:
    print('Same shape')
    Axes3D.plot_surface(X, Y, Z)

So I have no idea why it will not work. Even when I use X for Z like this (since it didn't complain about X missing or being the wrong shape) it still gets mad.

Axes3D.plot_surface(X, Y, X)

Edit: In looking around examples and trying things out, I finally got it to work. I hardly consider this solved though, because I still have no idea why one way works and another doesn't, and I don't want to leave this unsolved for posterity. I got it to work by doing this

surf = ax.plot_surface(X, Y, Z)

instead of "Axes3D.plotsurface()". I have no idea why this change got it to work, so please still help me figure this out.

Community
  • 1
  • 1
Liam Clink
  • 189
  • 1
  • 11
  • This is kinda along the right lines: – Liam Clink Mar 27 '16 at 04:44
  • But the problem is that I already have the array previously generated. I may rewrite it like this later, but that's not what I need now. I can't see why it won't plot as is. – Liam Clink Mar 27 '16 at 04:45
  • 1
    I ran into this as well - the documentation seems to suggest you can use it like this, but you can't at all. If you do `Axes3D.plot_surface(X=X,Y=Y,Z=Z)` you'll see that it's missing `self`. This seems to be a version 1.0.0 change that's left the docs a bit confused. – OJFord Mar 19 '17 at 12:11

1 Answers1

3

As you said, it seems that the right way to do this is via axis object (ax in the code below):

fig = plt.figure()
ax = fig.gca(projection='3d')
ax.plot_surface(X, Y, Z)

Alternatively, you can still call it using Axes3D, but then you need to pass it the axis object ax, like so:

Axes3D.plot_surface(ax, X, Y, Z)
S. Sergei
  • 31
  • 2