使用最少的插值绘制 3D 绘图

Ago*_*ino 5 python 3d numpy matplotlib

我正在绘制 3D 散点图,从文件中读取我的值。该文件的每一行都有 3 个坐标和一个标准差。让我们暂时将错误放在一边。

import os
import numpy as np
import matplotlib.pyplot as plt

input_file = os.path.normpath('C:/Users/sturaroa/Documents/my_file.tsv')

# read data from file
my_data = np.genfromtxt(input_file, delimiter='\t', skiprows=0)
X = my_data[:, 0]  # 1st column
Y = my_data[:, 1]  # 2nd column
Z = my_data[:, 2]  # 3rd column
errors = my_data[:, 3]  # 4th column (errors)

# draw 3D scatter graph
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.scatter(X, Y, Z)
Run Code Online (Sandbox Code Playgroud)

我明白了 3d_散点图

画廊中有一个很好的例子,它绘制了表面和轮廓的投影(下图)。我需要有一个类似的表示,同时尽可能少地阐述我的数据(以防止扭曲)。

轮廓f3d_demo2

我知道这个问题解释了如何从不规则的 3D 数据中获取 3D 表面。但是,它会“平滑”曲线,并插值到一组规则的点。我读过有关griddata 的文档,它说它返回一个

2d 浮点数组 - 在 (xi, yi) 点插值的值数组。

不是我想要的。有人告诉我,我绝对需要插值才能找到曲面。蚂蚁这可能是真的。其他一些人也告诉我插值不好,因为它会强制形状。这可能也是正确的(对于“插值”的大值)。

如何用最少的插值获得像样的 3D 图形?是否有类似将最近的 3D 点连接在一起的方法?

顺便说一句,我的数据相当规则,就像它们被组织为一组 2D 平面或“切片”,但我想知道在不做出这种假设的情况下这是否可能。

这是一个示例文件,它与散点图使用的相同。它简单且常规,如果可能的话,我建议测试更通用的一个。

2    1    2.0    0.0
2    2    82.666664    35.30187
2    3    100.0    0.0
2    4    98.0    4.472136
2    7    100.0    0.0
2    12    100.0    0.0
2    15    100.0    0.0
2    17    100.0    0.0
2    21    100.0    0.0
2    24    100.0    0.0
3    1    2.0    0.0
3    2    4.0    0.0
3    3    6.0    0.0
3    4    8.181818    0.60302263
3    7    15.090909    1.8683975
3    12    53.454544    33.6344
3    15    97.09091    3.9358494
3    17    97.09091    3.9358494
3    21    97.09091    3.3898242
3    24    97.09091    3.5058389
4    1    2.0    0.0
4    2    4.0    0.0
4    3    6.0    0.0
4    4    8.0    0.0
4    7    14.0    0.0
4    12    24.0    0.0
4    15    30.333334    0.74535596
4    17    37.666668    2.1343749
4    21    48.0    5.1639776
4    24    92.0    11.075499
Run Code Online (Sandbox Code Playgroud)

较长的示例输入。前 2 列应该是int,最后 2 列应该是float

这是改进的加载,以防万一

# tell numpy the first 2 columns are int and the last 2 are floats
my_data = np.genfromtxt(infile, dtype=[('a', '<i8'), ('b', '<i8'), ('x', '<f8'), ('d', '<f8')])

# access columns by name
print(my_data["b"]) # column 1
Run Code Online (Sandbox Code Playgroud)

Kon*_*ert 1

您想要绘制一个完全穿过所有数据点的曲面,并且“直接”这样做而不进行平滑处理。

我最近用 matplotlib 创建了这个图: 在此输入图像描述

我不想声称它具有最小的“平滑度”,但至少它完全通过了所有数据点。

我使用了matplotlib 中的plot_surface函数。您可能还想使用plot_wireframe

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(xGrid, yGrid, zGrid, rstride=1, cstride=1,cmap="autumn")
Run Code Online (Sandbox Code Playgroud)

我认为部分技巧是设置rstride=1cstride=1。您可能想验证这一点。具有更深入洞察力的人可能能够更好地解释这一点,在文档中它只是说步幅是采样长度。