移动三角形以匹配colormap

时间:2013-11-18 17:24:41

标签: python matplotlib triangulation

这个问题是前一个one的续集,但是这次是色彩图和三角形的顺序。我想在一个曲面上插入实验数据,以便启用一个连续的颜色映射,但是只有在其角节点处才知道表面。为了进行插值,我提出了一个规范的例子,该例子非常有效,但在实际数据上失败了。

确实如下面的示例所示,初始三角测量导致两个三角形之间存在巨大间隙,参见第一张图片。插值完成后,它不会变得更好,色彩图也会丢失,参见第二张照片。到目前为止最好的是通过颠倒z和y从头开始获得相邻的三角形,这导致成功的插值。然而,正如您在第三张图片中可能注意到的那样,表面倾斜90°这是正常的,因为我将y切换为z,反之亦然。

然而,当我使用ax.plot_trisurf(new.x, new_z, new.y, **kwargs)切换回tri_surf函数中的y和z时,颜色图不会跟随,参见图4。

我想过以某种方式旋转色彩图或者用triang = tri.Triangulation(new.x, new_z)从插值的三角形中生成新的三角形,但没有任何成功。所以任何想法或提示都要正确地对两个相邻的三角形进行初始三角测量,就像第三张图片一样,但是表面方向相关,最终颜色图与Y值成正比。

import numpy
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from matplotlib import cm
import matplotlib.tri as tri

x=numpy.array([0.00498316, 0.00498316, 0.00996632, 0.00996632])
y=numpy.array([-0.00037677, -0.00027191, -0.00078681, -0.00088475])
z=numpy.array([0., -0.0049926, 0., -0.00744763])

# Initial Triangle    
fig = plt.figure()
ax = Axes3D(fig)
triang = tri.Triangulation(x, y)

norm = plt.Normalize(vmax=y.max(), vmin=y.min())
ax.plot_trisurf(x, y, z, triangles=triang.triangles)

# Interpolated Triangle
fig = plt.figure()
ax = Axes3D(fig)
triang = tri.Triangulation(x, y)
refiner = tri.UniformTriRefiner(triang)
interpolator = tri.LinearTriInterpolator(triang, z)
new, new_z = refiner.refine_field(z, interpolator, subdiv=4)

kwargs = dict(triangles=new.triangles, cmap=cm.jet, norm=norm, linewidth=0,     antialiased=False)
ax.plot_trisurf(new.x, new.y, new_z, **kwargs)

# Best so far
fig = plt.figure()
ax = Axes3D(fig)
triang = tri.Triangulation(x, z)
refiner = tri.UniformTriRefiner(triang)
interpolator = tri.LinearTriInterpolator(triang, y)
new, new_z = refiner.refine_field(y, interpolator, subdiv=4)

kwargs = dict(triangles=new.triangles, cmap=cm.jet, norm=norm, linewidth=0, antialiased=False)
ax.plot_trisurf(new.x, new.y, new_z, **kwargs)

plt.show()

enter image description here enter image description here enter image description here enter image description here

1 个答案:

答案 0 :(得分:1)

显然,自动三角测量不会为您生成正确的三角形,但您可以手动指定三角形的颜色:

triang = tri.Triangulation(x, y, [[3,2,1],[1,2,0]])

# alternatively:
triang = tri.Triangulation(x, y, [[3,2,0],[1,3,0]])

这两种方式给出了不同的结果:

on the left: [[3,2,1],[1,2,0]], on the right: [[3,2,0],[1,3,0]]

然而,现在插值变得笨拙,因为对于某些(x,y),存在多个z值。绕过此问题的一种方法是分别插值和绘制2个大三角形:

import numpy
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from matplotlib import cm
import matplotlib.tri as tri


def plot_refined_tri(x, y, z, ax, subdiv=4, **kwargs):
    triang = tri.Triangulation(x, y)
    refiner = tri.UniformTriRefiner(triang)
    interpolator = tri.LinearTriInterpolator(triang, z)
    new, new_z = refiner.refine_field(z, interpolator, subdiv=subdiv)
    ax.plot_trisurf(new.x, new.y, new_z, triangles=new.triangles, **kwargs)


x=numpy.array([0.00498316, 0.00498316, 0.00996632, 0.00996632])
y=numpy.array([-0.00037677, -0.00027191, -0.00078681, -0.00088475])
z=numpy.array([0., -0.0049926, 0., -0.00744763])

fig = plt.figure()
ax = Axes3D(fig)
# note: I normalized on z-values to "fix" the colormap
norm = plt.Normalize(vmax=z.max(), vmin=z.min())
kwargs = kwargs = dict(linewidth=0.2, cmap=cm.jet, norm=norm)

idx = [3,2,1]
plot_refined_tri(x[idx], y[idx], z[idx], ax, **kwargs)

idx = [1,2,0]
plot_refined_tri(x[idx], y[idx], z[idx], ax, **kwargs)

plt.show()

结果:

This looks good