1

Is there anyway to plot surface in Python by only having X, Y, Z coordinates?

I have column vectors of X, Y, Z values where Z=F(X,Y) is already calculated ( I only have the data not the function )

import matplotlib.pyplot as plt
import numpy as np

fig = plt.figure(figsize = (12,10))
ax = plt.axes(projection='3d')

x = np.arange(-5, 5.1, 0.2)
y = np.arange(-5, 5.1, 0.2)

X, Y = np.meshgrid(x, y)
Z = np.sin(X)*np.cos(Y)

surf = ax.plot_surface(X, Y, Z, cmap = plt.cm.cividis)

# Set axes label
ax.set_xlabel('x', labelpad=20)
ax.set_ylabel('y', labelpad=20)
ax.set_zlabel('z', labelpad=20)

fig.colorbar(surf, shrink=0.5, aspect=8)

plt.show()

Examples like above in the manual consider that you can calculate Z = np.sin(X)*np.cos(Y)

But I cannot do that since I don't have the function.

Is there anyway to plot surface with only having X, Y, Z values in Python?

M.Jones
  • 135
  • 6
  • @Tom The problem is the Z shape. Run the example code provided. Print(Z) My Z shape is column vector of F(X,Y) values. – M.Jones Aug 21 '21 at 15:33
  • 1
    Gotcha, sorry I see that now! Will look a little more – Tom Aug 21 '21 at 15:37
  • 3
    You don't need to have a Z-function for `ax.plot_surface`. But you need to have Z-values for each point of a 2D grid of X-Y values. Note that `np.meshgrid(x, y)` in the example code creates a 2D grid out of 2 1D arrays, and therefore Z is a 2D array of values. If you have ungridded XYZ values, you can use [`ax.plot_trisurf`](https://stackoverflow.com/questions/51891538/create-a-surface-plot-of-xyz-altitude-data-in-python) – JohanC Aug 21 '21 at 16:12
  • @JohanC Is trisurf the only way? is not there any hack to be able to use plot_surface? – M.Jones Aug 21 '21 at 17:20
  • Why? You could create some triangulation and interpolate Z-Values for a regular grid. Lots of work to emulate the out-of-the-box `ax.plot_trisurf`. However, if your X and Y values are already situated on a regular grid, `ax.plot_surface` would be the way to go. Your post doesn't contain enough information to help here. – JohanC Aug 21 '21 at 17:26
  • You could as well as replace ``Z = np.sin(X)*np.cos(Y)`` with ``Z = np.random.rand(len(x),len(y))`` and the code will still plot just fine. The Z values don't necessarily have to be a function of X and Y – Karina Aug 23 '21 at 11:34
  • @Karina Well I have got a Z value and I want to plot that specific Z value not some random matrix! – M.Jones Aug 23 '21 at 18:23
  • basically, I was saying: even random would work, why wouldn't yours? Just replace this line ``Z = np.sin(X)*np.cos(Y)`` with your specific Z value. It doesn't matter. – Karina Aug 24 '21 at 07:04
  • @Karina A column vector of Z values won't work. – M.Jones Aug 24 '21 at 12:17
  • why don't you just post your sample data in the question? – Karina Aug 24 '21 at 12:22
  • @Karina My sample data is (N, 3) matrix where N is arbitrary. Column1 is x, column2 is y, column 3 is z. In the code above I've posted as an example use of plot_surface if you print(Z) you will see that it returns a matrix but I have a column of Z values not a matrix and that's where the problem lies. I cannot use plot_surface because of that. – M.Jones Aug 24 '21 at 13:29
  • Well, I say it could work. ``Z = np.tile(z, (len(x), 1))`` will do the trick. In this case, ``z`` has the shape like yours. – Karina Aug 24 '21 at 14:15

0 Answers0