6

For the life of me I cannot figure out how to get the same results as this.

The link generates the colored 3d plot without using contour. If I utilize the same technique but with my own x,y,z data set I get just one color.

The difference must be in the way I'm generating the z data for the plot.

Anyway, using this:

from mpl_toolkits.mplot3d import Axes3D
from matplotlib.mlab import griddata
from matplotlib import cm
from matplotlib.ticker import LinearLocator, FormatStrFormatter
import matplotlib.pyplot as plt
import numpy as np
import sys

def xyz_ret(file):
    f = open(file, 'r')

    xyz = []
    for i in f:
        ret = i.replace('\n','')
        xyz.append(map(float,(ret.split('\t'))))

    xyz =  np.array(xyz)   
    return xyz[:,0],xyz[:,1],xyz[:,2]     


x,y,z = xyz_ret('300.txt')

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

xi = np.linspace(min(x), max(x))
yi = np.linspace(min(y), max(y))

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

surf = ax.plot_surface(X, Y, Z, rstride=6, cstride=6, cmap=cm.jet,
        linewidth=0)

ax.set_zlim3d(min(z), max(z))

ax.w_zaxis.set_major_locator(LinearLocator(10))
ax.w_zaxis.set_major_formatter(FormatStrFormatter('%.03f'))

fig.colorbar(surf, shrink=0.5, aspect=5)

plt.show()

Data set:

-2187.99902 9380.009151 0.0209
-2187.00111 2474.994061 0.022
-10755.98931 6119.598968 0.0296
-5781.347693 609.427388 0.0301
-8761.562524 1942.391853 0.0285
-5695.576244 1894.624701 0.0251
-3801.215106 1096.153308 0.0257
-1616.821487 2452.940102 0.0182
-5790.547537 2975.622971 0.022
-8095.18467 4074.330871 0.0208
-9997.367785 2771.330212 0.0264
-10547.5635 4397.127096 0.0251
-5781.706776 3984.545588 0.0191
-3346.855289 4347.670408 0.0172
-918.639762 4518.515925 0.0142
-892.428381 5850.710005 0.0143
-5844.499993 6516.904257 0.0204
-10877.96951 6015.755723 0.0265
-10813.37291 7704.306099 0.0302
-7991.878303 7733.626264 0.0223
-5861.073574 8725.943697 0.0217
-3188.107715 6997.19893 0.0206
-897.427629 7474.426336 0.0188
-1388.841321 8786.642046 0.0194
-3370.72325 8825.154803 0.0225
-8561.226722 8851.111988 0.0285
-10275.58972 8849.798032 0.0341
-5853.645621 10113.77051 0.0255
-8101.002878 10754.8429 0.0332
-5765.080546 11378.95524 0.0299
-3081.969839 10549.46676 0.0242

Only one color is shown. Also notice the color bar has no ticks.

Can you explain what my problem is?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
hl3fx
  • 61
  • 1
  • 1
  • 2
  • I would say you are not using Axes3D.plot_surface. You import Axes3D but then you do not use it. – joaquin Dec 06 '10 at 07:18
  • Its used in ax = fig.add_subplot(111, projection='3d'), If i remove the Axes3d the script will error at that line. – hl3fx Dec 06 '10 at 09:26

3 Answers3

17

I think there is a problem with fill "discontinuous" surface (griddata). alt text

Code:

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

fig = plt.figure()
ax = fig.gca(projection='3d')

data = np.genfromtxt('300.txt')
x = data[:,0]
y = data[:,1]
z = data[:,2]

xi = np.linspace(min(x), max(x))
yi = np.linspace(min(y), max(y))

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

surf = ax.plot_surface(X, Y, Z, rstride=5, cstride=5, cmap=cm.jet,
                       linewidth=1, antialiased=True)

ax.set_zlim3d(np.min(Z), np.max(Z))
fig.colorbar(surf)

plt.show()

Please note that if you consider the surface above a rectangular area (xi x yi), this code is working properly. In other words, if you "cut off" irregular edges.

xi = np.linspace(-4000, -9000)
yi = np.linspace(4000, 9000)

alt text

kros
  • 1,257
  • 12
  • 19
  • Thank you for the feedback. I'm still trying to figure it out. I wonder if there is another way to get the z data without using griddata? – hl3fx Dec 07 '10 at 02:54
  • Would a symptom of the above also be the lack of tick marks in the color bar? I think these two problems are directly related. in the example code the ticks are shown representing the different colors to z height. If you print Z in the example code an array of lists is shown filled with numbers, in the above code if you print Z a list of --- is shown. Any ideas? – hl3fx Dec 07 '10 at 03:03
  • hmm, thank you for finding that. Now how to fix the broken surface? I found someone else with the same issue here: http://old.nabble.com/plot_surface-masked-array-tt27266471.html#a27266471 . Unfortunately there was no response to his question. – hl3fx Dec 08 '10 at 10:23
  • The surface is not broken, but the values of `Z` are not specified for all points `(xi, yi)` http://i.imgur.com/P8CHH.png. I have no idea how to fill irregular surface. – kros Dec 08 '10 at 12:18
  • Ill take this to the matplotlib mailing list to see if anyone there might have an idea and update later. Thanks for all your help so far. – hl3fx Dec 09 '10 at 03:46
  • 1
    `mlab.griddata` has been deprecated in favor of `scipy.interpolate.griddata` which requires slightly different arguments: `Z = griddata((x, y), z, (X.flatten(), Y.flatten()), 'nearest').reshape(50,50)`. (50 is the default `num` for `np.linspace`) – Leopd Jan 16 '20 at 23:08
2

I just struggled with the similar problem.

Finally I had to use natgrid (which is referenced here but the link doesn't work) instead of griddata.

for me the trick with cutting of plot region didn't work, it was always in one colour.

When installing PyNGL check that you have the latest version of numpy.

Good luck

Darshana
  • 2,462
  • 6
  • 28
  • 54
2

The easiest way to read text data is via genfromtxt:

data = np.genfromtxt('300.txt')
x = data[:,0]
y = data[:,1]
z = data[:,2]

sys is not required.

kros
  • 1,257
  • 12
  • 19