5

I'd like to ask how to generate corresponding values from a meshgrid. I have a function "foo" that takes one 1D array with the length of 2, and returns some real number.

import numpy as np

def foo(X):  
    #this function takes a vector, e.g., np.array([2,3]), and returns a real number.
    return sum(X)**np.sin( sum(X) );

x = np.arange(-2, 1, 1)          # points in the x axis
y = np.arange( 3, 8, 1)          # points in the y axis
X, Y = np.meshgrid(x, y)         # X, Y : grid

I generate X and Y grids using meshgrid.

Then, how can I generate corresponding Z values using "foo" function, in order to plot them in 3D, e.g., plotting using plot_surface function with X,Y,Z values?

Here the question is how to generate Z values, which has the same shape to X and Y, using "foo" function. Since my "foo" function only takes an 1D array, I do not know how I can uses this function with X and Y to generate corresponding Z values.

1
  • Do you want z = foo([x, y]) for each point (x, y) in the meshgrid? Commented Sep 27, 2016 at 0:30

1 Answer 1

3

Stack your two numpy arrays in "depth" using np.dstack, and then modify your foo function, so that it operates on only the last axis of your stacked array. This is easily done using np.sum with parameter axis=-1, instead of using the builtin sum:

import numpy as np

def foo(xy):
    return np.sum(xy, axis=-1) ** np.sin(np.sum(xy, axis=-1))

x = np.arange(-2, 1, 1)          # points in the x axis
y = np.arange( 3, 8, 1)          # points in the y axis
X, Y = np.meshgrid(x, y)         # X, Y : grid
XY = np.dstack((X, Y))

And now, you should get:

>>> XY.shape
(5, 3, 2)
>>> foo(XY)
array([[ 1.        ,  1.87813065,  1.1677002 ],
       [ 1.87813065,  1.1677002 ,  0.35023496],
       [ 1.1677002 ,  0.35023496,  0.2136686 ],
       [ 0.35023496,  0.2136686 ,  0.60613935],
       [ 0.2136686 ,  0.60613935,  3.59102217]])

If you want to achieve the same effect, but without modifying foo, then you can use np.apply_along_axis, which should do exactly what you need:

>>> np.apply_along_axis(foo, -1, XY)
array([[ 1.        ,  1.87813065,  1.1677002 ],
       [ 1.87813065,  1.1677002 ,  0.35023496],
       [ 1.1677002 ,  0.35023496,  0.2136686 ],
       [ 0.35023496,  0.2136686 ,  0.60613935],
       [ 0.2136686 ,  0.60613935,  3.59102217]])
Sign up to request clarification or add additional context in comments.

7 Comments

Thanks for the wonderful solution. This is exactly what I wanted to do. However, I have some problems to apply this approach to my code bock. I actually posted another question regarding this matter link. My actual foo function is actually something like return X[0] + X[1];, so it cannot perform an iterative operation on a nested array, and can only take the shape of (2,). Thus, if I put XY into my actual foo function, it spits our error. In this case, how can generate Z as you did?
Oops, sorry, I forgot it!
By the way, can you let me know how I should change your ode if I just want to use my current foo function, which can only take (2,) shape?
@AnnDescomp I've posted an answer on your other question. See if that works for you...
I am now looking at "..." indexing. In addition, I'd want to know if there is a way to generate Z with my current foo function, which can explicitly take only one (2,) shape Numpy array as an argument.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.