Kyriacos Xanthos
Kyriacos Xanthos

Reputation: 53

Surface Plot of 3D Arrays using matplotlib

I have a function of the form f(x,y,z) and want to create a surface plot for it (level sets) using matplotlib. The problem I have is that plot_surface only accepts 3 arguments, whereas the type of plot I want to do is create a grid of x,y,z values and then plot the value of my function f at each of those points.

Here is a minimal example:

import matplotlib as mpl
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib.pyplot as plt

bounds = [1,1,1]
numpoints = 25
x = np.linspace(-bounds[0], bounds[0], numpoints)
y = np.linspace(-bounds[1], bounds[1], numpoints)
z = np.linspace(-bounds[2], bounds[2], numpoints)

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

s = X.shape

Ze = np.zeros(s)
Zp = np.zeros(s)
DT = np.zeros((numpoints**3,3))

# convert mesh into point vector for which the model can be evaluated
c = 0
for i in range(s[0]):
    for j in range(s[1]):
        for k in range(s[2]):
            DT[c,0] = X[i,j,k]
            DT[c,1] = Y[i,j,k]
            DT[c,2] = Z[i,j,k]
            c = c+1;

# this could be any function that returns a shape (numpoints**3,)
Ep = np.square(DT)[:,0]

c = 0
for i in range(s[0]):
    for j in range(s[1]):
        for k in range(s[2]):
            Zp[i,j,k] = Ep[c]
            c = c+1;

Now I would like to plot Zp as level sets in matplotlib. Is this possible?

Upvotes: 1

Views: 631

Answers (1)

Salvatore Daniele Bianco
Salvatore Daniele Bianco

Reputation: 2701

The only way to represent 4 variables (x, y, x, f(x, y, z)) I could think in matplotlib is scatter the grid of x, y, z and give a color to the points that is proportional to f(x, y, z):

bounds = [1,1,1]
numpoints = 11
x = np.linspace(-bounds[0], bounds[0], numpoints)
y = np.linspace(-bounds[1], bounds[1], numpoints)
z = np.linspace(-bounds[2], bounds[2], numpoints)

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

For exaple let's say taht f(x,y,z)=sin(x+y)+cos(y+z):

f_xyz = np.sin(X+Y)+np.cos(Y+Z)

Now let's scatter:

plt.figure(figsize=(7,7))
ax = plt.subplot(projection="3d")
ax.scatter(X, Y, Z, s=10, alpha=.5, c=f_xyz, cmap="RdBu")
plt.show()

enter image description here

As you can see the result is a bit confusing and not very clear, but it strongly depends on what function you want to plot. I hope you could find a better way

Upvotes: 2

Related Questions