Home > Net >  Build 3D Object by define a function
Build 3D Object by define a function

Time:11-10

I have function z[i][j]=func(x[i],y[j]), where x and y are changing from -1 to 1 with step 0.1.

Need to build 3D object with z=sin(x y), when x<0 and z=cos(x y) when x>0

I made few variations (1 is working right (i guess)), but need to define a function

import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
x=np.linspace(-1,1,21)
y=np.linspace(-1,1,21)
x1,y1= np.meshgrid(x,y)
z = []
for i in x: 
    zz = [] 
    for j in y: 
        if i<0:
           zz.append(np.sin(i j))
        else:
           zz.append(np.cos(i j))
    z.append(zz)
fig=plt.figure(figsize=(5,6))
ax=fig.add_subplot(1,1,1,projection='3d')
ax.contour3D(x,y,z,10,cmap='inferno')
plt.show

UPD: I must import code (function) bellow in my working code, but dunno how to make it work with 3D plot)

import numpy as np
def func(x,y):
  if (x<0):
    return [np.sin(x y)]
  elif (x>0):
    return [np.cos(x y)]
  else:
    return [0]
print(func(1,4))
import numpy as np
import matplotlib.pyplot as plt
x=np.linspace(-1,1,21)
y=np.linspace(-1,1,21)
def fun(i,j): 
  for i in x: 
      fun = [] 
      for j in y: 
          if i<0:
            fun.append(np.sin(i j))
          else:
            fun.append(np.cos(i j))
fig=plt.figure(figsize=(5,6))
ax=fig.add_subplot(1,1,1,projection='3d')
ax.contour3D(x,y,fun(x,y),10,cmap='inferno')
plt.show

And error msg:

/usr/local/lib/python3.7/dist-packages/matplotlib/contour.py in _check_xyz(self, args, kwargs)
   1506 
   1507         if z.ndim != 2:
-> 1508             raise TypeError(f"Input z must be 2D, not {z.ndim}D")
   1509         if z.shape[0] < 2 or z.shape[1] < 2:
   1510             raise TypeError(f"Input z must be at least a (2, 2) shaped array, "

I really appreciate all the help :3

CodePudding user response:

You have few mistakes.

  1. you use the same name for def fun() and fun = [] and sometimes it can make big problem

  2. you use wrong names for arguments - you have fun(i, j) but later you use for ... in x:, for ... in y: so you need fun(x, y)

  3. in first version you use two lists z = [] and zz = [] and you append zz in z - but in function you use only one list - and this can be the biggest problem with 0D, 2D, 3D

  4. you have to use return ... to send values from function to main code.

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

# --- functions ---

def fun(x, y): 
    results = []  # z = []
    for i in x:
        row = []  # zz = []
        for j in y: 
            if i < 0:
                row.append(np.sin(i j))
            else:
                row.append(np.cos(i j))
        results.append(row)
    return results

# --- main ---

x = np.linspace(-1, 1, 21)
y = np.linspace(-1, 1, 21)
fig = plt.figure(figsize=(5, 6))
ax = fig.add_subplot(1, 1, 1, projection='3d')
ax.contour3D(x, y, fun(x, y), 10, cmap='inferno')
plt.show()

BTW:

You could also put some spaces to make code more readable - ie. space after ,, spaces around =, etc.

More: PEP 8 -- Style Guide for Python Code

  • Related