按条件屏蔽
下面是一个示例,说明如何使用 tricontourf 和遮罩来获得没有数据外插值部分的凹形。它依赖于根据条件屏蔽数据的能力。
import matplotlib.pyplot as plt
import matplotlib.tri as tri
import numpy as np
# create some data
rawx = np.random.rand(500)
rawy = np.random.rand(len(rawx))
cond01 = (rawx-1)**2 + rawy**2 <=1
cond02 = (rawx-0.7)**2 + rawy**2 >0.3
x = rawx[cond01 & cond02]
y = rawy[cond01 & cond02]
f = lambda x,y: np.sin(x*4)+np.cos(y)
z = f(x,y)
# now, x,y are points within a partially concave shape
triang0 = tri.Triangulation(x, y)
triang = tri.Triangulation(x, y)
x2 = x[triang.triangles].mean(axis=1)
y2 = y[triang.triangles].mean(axis=1)
#note the very obscure mean command, which, if not present causes an error.
#now we need some masking condition.
# this is easy in this case where we generated the data according to the same condition
cond1 = (x2-1)**2 + y2**2 <=1
cond2 = (x2-0.7)**2 + (y2)**2 >0.3
mask = np.where(cond1 & cond2,0,1)
# apply masking
triang.set_mask(mask)
fig, (ax, ax2) = plt.subplots(ncols=2, figsize=(6,3))
ax.set_aspect("equal")
ax2.set_aspect("equal")
ax.tricontourf(triang0, z, cmap="Oranges")
ax.scatter(x,y, s=3, color="k")
ax2.tricontourf(triang, z, cmap="Oranges")
ax2.scatter(x,y, s=3, color="k")
ax.set_title("tricontourf without mask")
ax2.set_title("tricontourf with mask")
ax.set_xlim(0,1)
ax.set_ylim(0,1)
ax2.set_xlim(0,1)
ax2.set_ylim(0,1)
plt.show()
按最大边长掩码
如果您无法获得确切的条件,但具有点之间的最大边长(距离),则以下将是一个解决方案。它将掩盖至少一侧长于某个最大距离的所有三角形。如果点密度相当高,这可以很好地应用。
import matplotlib.pyplot as plt
import matplotlib.tri as tri
import numpy as np
# create some data
rawx = np.random.rand(500)
rawy = np.random.rand(len(rawx))
cond01 = (rawx-1)**2 + rawy**2 <=1
cond02 = (rawx-0.7)**2 + rawy**2 >0.3
x = rawx[cond01 & cond02]
y = rawy[cond01 & cond02]
f = lambda x,y: np.sin(x*4)+np.cos(y)
z = f(x,y)
# now, x,y are points within a partially concave shape
triang1 = tri.Triangulation(x, y)
triang2 = tri.Triangulation(x, y)
triang3 = tri.Triangulation(x, y)
def apply_mask(triang, alpha=0.4):
# Mask triangles with sidelength bigger some alpha
triangles = triang.triangles
# Mask off unwanted triangles.
xtri = x[triangles] - np.roll(x[triangles], 1, axis=1)
ytri = y[triangles] - np.roll(y[triangles], 1, axis=1)
maxi = np.max(np.sqrt(xtri**2 + ytri**2), axis=1)
# apply masking
triang.set_mask(maxi > alpha)
apply_mask(triang2, alpha=0.1)
apply_mask(triang3, alpha=0.3)
fig, (ax1, ax2, ax3) = plt.subplots(ncols=3, figsize=(9,3))
ax1.tricontourf(triang1, z, cmap="Oranges")
ax1.scatter(x,y, s=3, color="k")
ax2.tricontourf(triang2, z, cmap="Oranges")
ax2.scatter(x,y, s=3, color="k")
ax3.tricontourf(triang3, z, cmap="Oranges")
ax3.scatter(x,y, s=3, color="k")
ax1.set_title("tricontourf without mask")
ax2.set_title("with mask (alpha=0.1)")
ax3.set_title("with mask (alpha=0.3)")
for ax in (ax1, ax2, ax3):
ax.set(xlim=(0,1), ylim=(0,1), aspect="equal")
plt.show()
可以看出,在这里找到正确的参数 (alpha) 可能需要一些调整。