如何用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
相关产品推荐
相关产品推荐

