如何使用plot_trisurf函数

4

在将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个点。以下是其中一部分内容,完整文件可以在这里找到。

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之前,我可以得到如下结果:]

谢谢您的回复,但我提供了一个包含38010个点的文件。以上数据仅显示了极小的一部分,以说明数据格式。 - zxgao
详细信息请参见链接 - zxgao
我可以确认trisurf图仅绘制了部分点。我不知道原因在哪里,但它一定存在于三角剖分或trisurf图本身中的某个地方。我在您提出的GitHub问题中添加了一些可重现的代码。 - ImportanceOfBeingErnest
我认为问题现在已经解决,在GitHub Issue讨论串中。@zxgao,你是否愿意根据它提供一个答案? - ImportanceOfBeingErnest
1个回答

2
非常感谢所有回复。这个问题已经得到解决,详细信息请参见matplotlib 2.0.2的plot_trisurf问题。 在此,我很高兴展示我的结果。 问题在于在qhull计算Delaunay三角剖分时存在有限精度问题,它认为接近(根据“接近”一词的复杂定义)的点是相同的,因此三角剖分比所需简单。该数据集是极端的(不好的方式)对于有限精度而言,因为点围绕其平均值的传播很小(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()

之前,结果显示为: enter image description here

之后,结果显示为: enter image description here

因此,总结一下,这实际上不是不同matplotlib版本之间的问题,当前版本已经足够应对大多数使用情况。如果有人希望轴刻度标签可以轻松修正,可以参考ImportanceOfBeingErnest的方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接