You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python绘制带孔洞的不规则几何体热力图

问题

我有一个带孔洞的不规则几何体,已经获取了所有点的(x,y)坐标及幅值z。用插值绘制热力图时,孔洞区域也被插值计算并填充了颜色。我希望生成仅覆盖几何体有效区域(基于插值数据生成平滑图像,不是网格点直接描边)、孔洞显示为白色空白的热力图,请问能否实现?

我尝试的代码如下:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import griddata


data = pd.read_excel('file.xlsx', skiprows=4)
data = np.array(data)


x = data[:,0]
y = data[:,1]
z = data[:,2]

# 定义网格
xi = np.linspace(np.min(x),np.max(x))
yi = np.linspace(np.min(y),np.max(y))

# 插值生成网格数据
zi = griddata((x, y), z, (xi[None,:], yi[:,None]), method='cubic')

# 绘制等高线和填充热力图
CS = plt.contour(xi,yi,zi,15,linewidths=0.5,colors='k')
CS = plt.contourf(xi,yi,zi,15,cmap=plt.cm.jet)
plt.colorbar() # 绘制颜色条

当前生成的热力图效果:
当前热力图


解决方案

完全可以实现。核心思路是先标记出网格中属于几何体有效区域的点,将孔洞等无效区域的插值结果设为np.nan,matplotlib会自动忽略nan值,显示为空白。具体实现如下:

修改后的代码

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import griddata
from matplotlib.path import Path

# 读取数据
data = pd.read_excel('file.xlsx', skiprows=4)
data = np.array(data)
x = data[:,0]
y = data[:,1]
z = data[:,2]

# 定义更精细的网格(提升平滑度)
xi = np.linspace(np.min(x), np.max(x), 100)
yi = np.linspace(np.min(y), np.max(y), 100)
xi_grid, yi_grid = np.meshgrid(xi, yi)

# 插值生成网格数据
zi = griddata((x, y), z, (xi_grid, yi_grid), method='cubic')

# -------------------------- 核心:标记有效区域 --------------------------
# 替换为你自己的外轮廓和孔洞轮廓点(每行是(x,y)坐标)
# 示例:外轮廓为矩形,孔洞为内部小矩形
outer_boundary = np.array([[np.min(x), np.min(y)], [np.max(x), np.min(y)], 
                           [np.max(x), np.max(y)], [np.min(x), np.max(y)]])
hole_boundary = np.array([[20, 20], [30, 20], [30, 30], [20, 30]])

# 创建路径:外轮廓顺时针,孔洞逆时针(符合Path的区域识别规则)
vertices = np.vstack([outer_boundary, hole_boundary])
codes = [Path.MOVETO] + [Path.LINETO]*(len(outer_boundary)-1) + [Path.CLOSEPOLY,
                         Path.MOVETO] + [Path.LINETO]*(len(hole_boundary)-1) + [Path.CLOSEPOLY]
path = Path(vertices, codes)

# 判断每个网格点是否在有效区域内
points = np.vstack([xi_grid.ravel(), yi_grid.ravel()]).T
is_inside = path.contains_points(points).reshape(xi_grid.shape)

# 无效区域设为nan,matplotlib会自动留白
zi[~is_inside] = np.nan
# -----------------------------------------------------------------------

# 绘制最终热力图
CS = plt.contour(xi_grid, yi_grid, zi, 15, linewidths=0.5, colors='k')
CS = plt.contourf(xi_grid, yi_grid, zi, 15, cmap=plt.cm.jet)
plt.colorbar()
plt.show()

关键注意点

  • 轮廓点顺序:外轮廓建议按顺时针排列,孔洞轮廓按逆时针排列,确保Path能正确识别孔洞区域。
  • 轮廓获取:如果没有现成的轮廓点,可以从原始数据中提取边界(比如用聚类算法筛选边缘点),或者手动标注轮廓坐标。
  • 网格精度:np.linspace的第三个参数(网格点数)越大,热力图越平滑,边界细节越清晰。

内容的提问来源于stack exchange,提问作者Ellis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 06:40:21