7

I'm trying to understand how to build arrays for use in plot_surface (in Axes3d). I tried to build a simple surface manipulating data of those arrays:

In [106]: x
Out[106]: 
array([[0, 0],
       [0, 1],
       [0, 0]])

In [107]: y
Out[107]: 
array([[0, 0],
       [1, 1],
       [0, 0]])

In [108]: z
Out[108]: 
array([[0, 0],
       [1, 1],
       [2, 2]])

But I can't figure out how they are interpreted - for example there is nothing in z=2 on my plot. Anybody please explain exactly which values will be taken to make point, which for line and finally surface.

For example I would like to build a surface that would connect with lines points: [0,0,0]->[1,1,1]->[0,0,2] [0,0,0]->[1,-1,1]->[0,0,2] and a surface between those lines. What should arrays for plot_surface look like to get something like this?

Adam Pierzchała
  • 2,244
  • 4
  • 30
  • 32
  • Possible duplicate of [surface plots in matplotlib](http://stackoverflow.com/questions/9170838/surface-plots-in-matplotlib) – Ramon Crehuet Mar 22 '17 at 11:24

2 Answers2

3

Understanding how the grids in plot_surface work is not easy. So first I'll give a general explanation, and then I'll explain how to convert the data in your case. If you have an array of N x values and an array of M y values, you need to create two grids of x and y values of dimension (M,N) each. Fortunately numpy.meshgrid will help. Confused? See an example:

x = np.arange(3)
y=np.arange(1,5)
X, Y = np.meshgrid(x,y)

The element (x[i], y[j]) is accessed as (X[j,i], Y[j,i]). And its Z value is, of course, Z[j,i], which you also need to define.

Having said that, your data does produce a point of the surface in (0,0,2), as expected. In fact, there are two points at that position, coming from coordinate indices (0,0,0) and (1,1,1).

I attach the result of plotting your arrays with:

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

enter image description here

Ramon Crehuet
  • 3,679
  • 1
  • 22
  • 37
1

If I understand you correctly you try to interpolate a surface through a set of points. I don't think the plot_surface is the correct function for this. But correct me if I'm wrong. I think you should look for interpolation tools, probably those in scipy.interpolate. The result of the interpolation can then be plotted using plot_surface.

plot_surface is able to plot a grid (with z values) in 3D space based on x, y coordinates. The arrays of x and y are those created by numpy.meshgrid.

example of plot_surface:

import pylab as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D

plt.ion()

x = np.arange(0,np.pi, 0.1)
y = x.copy()
z = np.sin(x).repeat(32).reshape(32,32)

X, Y = np.meshgrid(x,y)

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(X,Y,z, cmap=plt.cm.jet, cstride=1, rstride=1)
Niels
  • 153
  • 1
  • 6
  • Actually my final goal is to have a sphere like [here](http://matplotlib.sourceforge.net/examples/mplot3d/surface3d_demo2.html), but then I want to manipulate single points by putting them away or closer to the center of the sphere. And for this I need to understand what I need to modify in this sphere to move a single point. – Adam Pierzchała Jul 16 '12 at 05:23