使用python在指定曲线上方屏蔽/裁剪等高线图的一部分

Posted

技术标签:

【中文标题】使用python在指定曲线上方屏蔽/裁剪等高线图的一部分【英文标题】:Masking/clipping part of a contour plot above a specified curve with python 【发布时间】:2020-12-26 05:24:18 【问题描述】:

我有一个使用 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.5576,0.580,0.590, 0.593,0.597,0.600,0.604,0.607,0.610,0.613,0.616]

lefty = [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]

三角剖分/轮廓的网格是

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。您可以使用左曲线和右曲线的反转来创建剪辑形状。 【参考方案1】:

您可以创建类似于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()

【讨论】:

这看起来很棒!我会修改并用结果更新帖子。谢谢! 完美运行!为了让我的代码能够正常工作,我唯一要做的就是稍微调整一下并执行ax = plt.gca() cont = plt.contourf(xi, yi, zi, levels=9, cmap='hot') ax.add_patch(clip_patch) for col in cont.collections: col.set_clip_path(clip_patch) 您喜欢plt.contourf() 并创建自己的三角测量而不是使用plt.tricontourf() 有什么特别的原因吗? 我似乎无法让plt.tricontourf() 处理我的数据,这确实是我决定创建自己的三角剖分的唯一原因。 :)

以上是关于使用python在指定曲线上方屏蔽/裁剪等高线图的一部分的主要内容,如果未能解决你的问题,请参考以下文章

等高线图未在 plotly python 中显示

android怎么让折线图上方显示数字

matlab画等高线图( z = f(x,y) )

拉格朗日乘子法

使用 R 绘制带有等高线图叠加的 3D 曲面图

使用 Plotly 在等高线图上叠加线