8

我正在尝试在 python 中创建一座山的表面图,其中我有一些 xyz 数据。最终结果应该是这样。该文件的格式如下:

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坐标,中间一列代表坐标yz海拔高度属于xy坐标。

我使用读取数据pandas,然后将列转换为单独的x, y, z NumPy1D 数组。到目前为止,我设法创建了一个简单的 3D 散点图,其中for循环遍历每个 1D 数组的每个索引,但这需要很长时间并且看起来效率很低。

我尝试使用scipy.interpolate.griddataand plt.plot_surface,但是对于z数据,我总是得到数据应该在 2D 数组中的错误,但我无法弄清楚它为什么或如何应该是 2D 数据。我假设鉴于我有 xyz 数据,应该有一种方法可以简单地从它创建一个表面。有简单的方法吗?

4

3 回答 3

6

使用函数plot_trisurfscatterfrom matplotlib,给定的X Y Z数据可以绘制成类似于给定的 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包含作为上述脚本参数提供的数据的文件
  • in plot_trisurf,用于控制外观的参数。例如alpha用于控制表面的不透明度
  • 在 中scatterc参数指定绘制在曲面上的点的颜色

对于给定的数据文件,生成以下图

在此处输入图像描述

注意:这里的地形是由一组给定的 3D 点进行三角剖分形成的。因此,绘图中沿表面的轮廓未与 X 轴和 Y 轴对齐

于 2019-03-08T15:42:36.903 回答
1
import numpy as np  
import matplotlib.pyplot as plt  
import mpl_toolkits.mplot3d 
import pandas as pd 
 
df = pd.read_csv("/content/1.csv") 
X = df.iloc[:, 0] 
Y = df.iloc[:, 1] 
Z = df.iloc[:, 2] 
 
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()

下面是我的输出图像 - 我有很多数据点: 在此处输入图像描述

于 2022-01-15T13:57:13.353 回答
0

有一种更简单的方法可以在不使用 pandas 的情况下实现您的目标。

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()

绘图示例

于 2018-08-17T08:57:51.430 回答