如何使用plot_trisurf

How to use plot_trisurf

matplotlib 版本从 1.3.1 更新到 2.0.2 后,当我想使用 plot_trisurf 生成 3d 点 TIN 时,我得到了无法理解的结果。我的测试代码如下:

import sys
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.ticker import MaxNLocator
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D
import numpy
from numpy.random import randn
from scipy import array, newaxis

chunk = numpy.loadtxt('test.xyz')  #test.xyz contains 38010 points,
DATA=numpy.array(chunk)
Xs = DATA[:,0]
Ys = DATA[:,1]
Zs = DATA[:,2]

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

surf = ax.plot_trisurf(Xs, Ys, Zs, cmap=cm.jet, linewidth=0)
fig.colorbar(surf)

ax.xaxis.set_major_locator(MaxNLocator(5))
ax.yaxis.set_major_locator(MaxNLocator(6))
ax.zaxis.set_major_locator(MaxNLocator(5))

fig.tight_layout()
plt.show()

test.xyz 文件包含 38010 个点。部分内容如下,完整文件见here.

512743.63 5403547.33 308.68
512743.62 5403547.33 308.70
512743.61 5403547.33 308.72
512743.60 5403547.34 308.68
512743.60 5403547.33 308.73
512741.50 5403547.36 309.05
512741.50 5403547.36 309.07
512741.49 5403547.46 309.09
512741.48 5403547.46 309.07
512741.47 5403547.46 309.10
512741.47 5403547.45 309.13
512741.46 5403547.37 309.04
512739.39 5403547.51 309.10
512739.39 5403547.48 309.34
512739.38 5403547.60 309.25
512739.37 5403547.71 309.15
512739.39 5403547.49 310.65
512739.39 5403547.48 310.70
512739.38 5403547.49 310.69
512739.37 5403547.48 310.72
512739.36 5403547.39 310.64
512739.32 5403547.41 309.20
512737.33 5403547.26 313.14
512737.33 5403547.37 313.09
512737.32 5403547.38 313.03
512737.30 5403547.37 313.12
512737.30 5403547.26 313.14
512735.22 5403547.41 311.72
512735.22 5403547.43 312.29
512735.22 5403547.49 312.59
512735.21 5403547.51 312.48
512735.20 5403547.60 312.53
512735.19 5403547.61 312.48
512735.18 5403547.72 312.40
512735.18 5403547.71 312.49
512735.17 5403547.71 312.51
512735.16 5403547.70 312.58
512735.15 5403547.61 312.52

更新后结果显示为:

我觉得不对,因为我提供了足够多的点来生成TIN,但是结果好像只用了一小部分点。在更新 matplotlib 之前,我可以获得如下结果:

非常感谢大家的回复。此问题已解决,详情见Problem about plot_trisurf of matplotlib 2.0.2。 在这里,我很高兴展示我的结果。 问题是在 qhull 中计算 Delaunay 三角剖分时的有限精度之一,它认为附近的点(根据单词 'near' 的复杂定义)是相同的,因此三角剖分比预期的要简单。该数据集是有限精度的极端数据集(以一种糟糕的方式),因为关于它们的平均值的点分布很小(x.mean()=512767,x.max()-x.min ()=134, y.mean()=303, y.max()-y.min()=5403707)。Ian Thomas对此进行了解释。 因此,我已将我的测试代码更正如下:

import sys
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.ticker import MaxNLocator
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D
import numpy
from numpy.random import randn
from scipy import array, newaxis

chunk = numpy.loadtxt('test.xyz')  #test.xyz contains 38010 points,
DATA=numpy.array(chunk)
Xs = DATA[:,0]
Ys = DATA[:,1]
Zs = DATA[:,2]

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
#surf = ax.plot_trisurf(Xs, Ys, Zs, cmap=cm.jet, linewidth=0)
surf = ax.plot_trisurf(Xs-Xs.mean(), Ys-Ys.mean(), Zs, cmap=cm.jet, linewidth=0)
fig.colorbar(surf)

ax.xaxis.set_major_locator(MaxNLocator(5))
ax.yaxis.set_major_locator(MaxNLocator(6))
ax.zaxis.set_major_locator(MaxNLocator(5))

fig.tight_layout()
plt.show()

之前,结果显示为:

之后,结果如图:

综上所述,这实际上不是不同 matplotlib 版本之间的问题,当前版本足以应付大多数用例。如果有人希望轴标记可以很容易地修正,你可以参考 ImportanceOfBeingErnest 的 method.