I have a function which is of the form :
def f(x, y):
total = 0
u = np.zeros(10)
for i in range(0,10):
u[i] = x * i + y* i
if u[i] < 10:
print('do something')
total = total + u[i]
return total
this function when i try with a given x and y values works well.
f(3,4)
Out[49]: 63.0
I want to create a 3d contour plot using matplotlib. Tried with
x = np.linspace(-6, 6, 30)
y = np.linspace(-6, 6, 30)
X, Y = np.meshgrid(x, y)
Z = f(X, Y)
fig = plt.figure()
ax = plt.axes(projection='3d')
ax.contour3D(X, Y, Z, 50, cmap='binary')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z');
I had to create a mesh grid for 3d plot. I get an error when I try with this because of the loop in my function. I get an error
ValueError: setting an array element with a sequence.
How to plot 3d graphs if my function has a loop?
You need np.vectorize:
# same setup as above, then
Z = np.vectorize(f)(X, Y)
import pylab as plt
plt.imshow(Z, extent=[x[0], x[-1], y[0], y[-1]])
(I checked with imshow but contour3D will work too.)
np.vectorize will take a function that accepts scalar (non-array) arguments and magically loops over arrays. It's nominally equivalent to:
Z2 = np.array([f(xx, yy) for xx in x for yy in y]).reshape(X.shape)
print(np.abs(Z - Z2).max()) # should print 0
but faster: after I remove the print in f:
In [47]: %timeit Z = np.vectorize(f)(X, Y)
6 ms ± 339 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [48]: %timeit Z2 = np.array([f(xx, yy) for xx in x for yy in y]).reshape(X.shape)
13.7 ms ± 310 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
(I had to remove the prints for timing because printing is Very Slow.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With