8

I have a 2D array that stores values of a property of each point as its element: f(x,y) = f[x][y]. Now I want to find the gradient of this array. I looked into np.gradient but it just gives two arrays as return, first with derivative in x direction and second in y direction.

I want to learn how can I use this or any other way to create a gradient map that shows the change in gradient of the 2D array.
varray is the 2D array I want to create gradient map of. Following is the only things I can think of right now. I know there should be clever way to use x gradientand y gradient generated by np.gradient() but I cannot think of it. lx and ly are x and y dimension of the 2D array.

vgrad = np.gradient(varray)
xgrad = vgrad[0]
x, y = range(0, lx), range(0,ly)
xi, yi = np.meshgrid(x, y)
rbf = scipy.interpolate.Rbf(xi, yi, xgrad)
plt.imshow(v, vmin = np.amin(xgrad), vmax=np.amax(xgrad))
plt.colorbar()
plt.show()  

I want to get basically the second image from the first image. The second image is described as σ = \alpha*grad(varray).

Using magnitude of gradient as suggested by @Mad Physicist below.

vgrad = np.gradient(varray)
fulgrad = np.sqrt(vgrad[0]**2 + vgrad[1]**2)
plt.imshow(fulgrad,cmap=plt.get_cmap('hot'), vmin = np.amin(fulgrad),vmax = np.amax(fulgrad))  
plt.colorbar()
plt.show()  

the image i get : enter image description here

I am interpreting this wrong from basic understanding of the equation?

So here is my images. On left: image of the initial 2D map. On right: Image of the gradient map. @Mad Physicist do you think they are similar to above with only difference of colors?

enter image description here enter image description here

jkhadka
  • 2,443
  • 8
  • 34
  • 56
  • 1
    You just need to use a different color map. The image you are getting is fine. Selecting the exact color map may be a bit difficult. How was the original expected image generated? – Mad Physicist Nov 30 '15 at 17:48
  • Here is a reference to known plt colormaps: http://matplotlib.org/examples/color/colormaps_reference.html. I think that your best bet is `Jet`. – Mad Physicist Nov 30 '15 at 17:53
  • @MadPhysicist Hey I added the images of before and after. Can you tell me if you think they are correct. It seems to be fine. I am bit concerned about the asymmetry of brightness near the tip of the pins as compared to theoretical picture above. But i guess that is error followed from first calculation (of left image). – jkhadka Nov 30 '15 at 18:09
  • At this stage I think the only major difference is the original input image seems to be much more discreet in terms of its color levels than yours. Naturally, the resulting map is much more discrete as well. If that is a normal artifact, I think you are OK at this point. – Mad Physicist Nov 30 '15 at 18:19
  • Thank you very much for this help. I also think the results are satisfactory. I guess they used better relaxation technique for creating first image than me. Also I am using `100x50` dimension where as they are using `400x200`, and I do not know their exact initial profile. – jkhadka Nov 30 '15 at 18:58

1 Answers1

8

If you are looking for the magnitude of the gradient, you can just do

mag = np.sqrt(vgrad[0]**2 + vgrad[1]**2)

Then plot mag instead of xgrad as above. If, you want to plot the gradient as a vector map or stream plot, do something like

plt.streamplot(xi, yi, vgrad[0], vgrad[1])

You may also be interested in the visual representation of the slope that can be obtained from just plotting the original surface in 3D:

fig = plt.figure()
ax = fig.gca(projection='3d')
surf = ax.plot_surface(xi, yi, varray)
plt.show()

See What is the equivalent of Matlab's surf(x,y,z,c) in matplotlib? and http://matplotlib.org/examples/mplot3d/surface3d_demo.html

Community
  • 1
  • 1
Mad Physicist
  • 107,652
  • 25
  • 181
  • 264
  • hey thanks for suggestion, I used what you said with magnitude of the gradient but I am not getting the result as close to above. I have also kept the result of what i get after using the magnitude. – jkhadka Nov 30 '15 at 17:38