Masking/clipping 指定曲线上方等高线图的一部分 python

Masking/clipping part of a contour plot above a specified curve with python

我有一个使用 Triangulation/TriInterpolation 和 contourf 生成的等高线图,如下图所示。我还在轮廓的两侧绘制了两条曲线,这些曲线是数据不应通过的边界。从左下角可以看出,数据溢出了左手线(我确定是由于三角测量试图连接三角形),我想找到一种方法来使用左手线来强制上面的所有内容它被屏蔽或剪辑,因为我将添加更多数据,这无疑会做同样的事情。

我曾尝试通过 matplotlib.patches 和正常遮罩使用剪辑,但似乎无法弄清楚。

左边一行的数据是这样的:

leftx = [0.319,0.373,0.407,0.432,0.452,0.469,0.483,0.495,0.506,0.516,0.525,0.533,0.541,0.548,0.554,0.560,0.566,0.571,0.580,0.55,0.571,0.580,0.5 0.589,0.593,0.597,0.600,0.604,0.607,0.610,0.613,0.616]

左撇子 = [0.5,1.0,1.5,2.0,2.5,3.0,3.5,4.0,4.5,5.0,5.5,6.0,6.5,7.0,7.5,8.0,8.5,9.0,9.5,10.0,10.5, 11.0,11.5,12.0,12.5,13.0,13.5,14.0,14.5,15.0]

triangulation/contourf 的网格是

xi = np.linspace(0, 1.2, 1000)
yi = np.linspace(0, 15.0, 1000)
Xi, Yi = np.meshgrid(xi, yi)
triang = tri.Triangulation(xdata,ydata)
interpolator = tri.LinearTriInterpolator(triang, zdata)
zi = interpolator(Xi, Yi)

我该怎么做?提前谢谢了! :)

您可以创建一个类似于 this post 的 clip_path。可以用左曲线和右曲线的反向来创建剪辑形状。

请注意,clip_path 需要添加到绘图中。这是确保所有点都转换到正确轴所必需的。可以用color='none'画出来让它不可见。

下面是一些测试代码,演示了它如何在您的情况下工作:

import matplotlib.pyplot as plt
from matplotlib import path as mpath
from matplotlib import patches as mpatches
import numpy as np

N = 100
xdata = np.random.uniform(0, 1.2, N)
ydata = np.random.uniform(0, 15, N)
zdata = np.random.uniform(0, 90, N)

leftx = np.array([0.319, 0.373, 0.407, 0.432, 0.452, 0.469, 0.483, 0.495, 0.506, 0.516, 0.525, 0.533, 0.541, 0.548, 0.554, 0.560, 0.566, 0.571, 0.576, 0.580, 0.585, 0.589, 0.593, 0.597, 0.600, 0.604, 0.607, 0.610, 0.613, 0.616])
lefty = np.array([0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 7.5, 8.0, 8.5, 9.0, 9.5, 10.0, 10.5, 11.0, 11.5, 12.0, 12.5, 13.0, 13.5, 14.0, 14.5, 15.0])
rightx = leftx + 0.6
righty = lefty
vertices = np.vstack([np.concatenate([leftx, rightx[::-1]]), np.concatenate([lefty, righty[::-1]])]).T
poly_codes = [mpath.Path.MOVETO] + (len(vertices) - 1) * [mpath.Path.LINETO]
path = mpath.Path(vertices, poly_codes)
clip_patch = mpatches.PathPatch(path, facecolor='none', edgecolor='none')
plt.gca().add_patch(clip_patch)

cont = plt.tricontourf(xdata, ydata, zdata, levels=10, cmap='hot')
for c in cont.collections:
    c.set_clip_path(clip_patch)

plt.show()