我正在尝试在python中创建一个山的表面图,其中我有一些xyz数据。最终的结果看起来应该像that。该文件的格式如下:
616000.0 90500.0 3096.712
616000.0 90525.0 3123.415
616000.0 90550.0 3158.902
616000.0 90575.0 3182.109
616000.0 90600.0 3192.991
616025.0 90500.0 3082.684
616025.0 90525.0 3116.597
616025.0 90550.0 3149.812
616025.0 90575.0 3177.607
616025.0 90600.0 3191.986
等等。第一列表示x
坐标,中间一列表示y
坐标,z
表示属于xy坐标的高度。
我使用pandas
读取数据,然后将列转换为单独的x
,y
,z
NumPy
1D数组。到目前为止,我设法创建了一个简单的三维散点图,其中for
循环迭代每个1D数组的每个索引,但这需要很长时间并且使得外观效率非常低。
我曾尝试使用scipy.interpolate.griddata
和plt.plot_surface
,但对于z
数据,我总是得到数据应该在2D数组中的错误,但我无法弄清楚为什么或如何应该是2D数据。我假设我有xyz数据,应该有一种简单的方法来创建一个表面。有一个简单的方法吗?
使用来自plot_trisurf
的函数scatter
和matplotlib
,给出X Y Z
数据可以绘制类似于given plot。
import sys
import csv
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d
# Read CSV
csvFileName = sys.argv[1]
csvData = []
with open(csvFileName, 'r') as csvFile:
csvReader = csv.reader(csvFile, delimiter=' ')
for csvRow in csvReader:
csvData.append(csvRow)
# Get X, Y, Z
csvData = np.array(csvData)
csvData = csvData.astype(np.float)
X, Y, Z = csvData[:,0], csvData[:,1], csvData[:,2]
# Plot X,Y,Z
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_trisurf(X, Y, Z, color='white', edgecolors='grey', alpha=0.5)
ax.scatter(X, Y, Z, c='red')
plt.show()
这里,
X Y Z
数据的文件作为上述脚本的参数提供plot_trisurf
中,用于控制外观的参数。例如alpha
曾用于控制表面的不透明度scatter
中,c
参数指定在曲面上绘制的点的颜色对于给定的数据文件,生成以下图
注意:这里,地形是由给定的一组3D点的三角测量形成的。因此,图中沿曲面的轮廓不与X轴和Y轴对齐
没有使用熊猫,有一种更简单的方法来实现您的目标。
import numpy as np
import matplotlib.pyplot as plt
import mpl_toolkits.mplot3d
x, y = np.mgrid[-2 : 2 : 20j, -2 : 2 : 20j]
z = 50 * np.sin(x + y) # test data
output = plt.subplot(111, projection = '3d') # 3d projection
output.plot_surface(x, y, z, rstride = 2, cstride = 1, cmap = plt.cm.Blues_r)
output.set_xlabel('x') # axis label
output.set_xlabel('y')
output.set_xlabel('z')
plt.show()