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

Matplotlib绘制非凸星形域XYZ散点数据热力图实现方案

非凸星形区域不规则采样点热力图实现方案

失效原因

常规griddata、无掩码contour类方法无法正确绘制该图形的核心原因:

  • 目标星形为非凸凹多边形,默认三角剖分会在凹口位置生成跨区域的三角形,把区域外的空间纳入插值计算
  • 未做区域范围掩码,区域外的错误插值结果会被直接绘制,出现图形溢出、错乱的问题

实现思路

  • 基于给定的星形边界坐标,创建多边形路径对象,用于判断任意坐标点是否在区域内部
  • 生成覆盖整个星形范围的高密度规则网格
  • 基于离散采样点做三角插值,得到所有网格点对应的Z值
  • 用多边形掩码过滤掉区域外的网格值,将其设为空值np.nan,绘制时自动跳过这部分内容
  • 渲染热力图,叠加边界线、可选的采样点标记,调整坐标轴比例避免图形变形

完整可运行代码

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.tri import Triangulation, LinearTriInterpolator
from matplotlib.path import Path

# 原始输入数据
coords= [(0.5, 0.0), (0.8660254037844387, 0.49999999999999994), (0.25000000000000006, 0.4330127018922193), (6.123233995736766e-17, 1.0), (-0.2499999999999999, 0.43301270189221935), (-0.8660254037844385, 0.5000000000000003), (-0.5, 6.123233995736766e-17), (-0.8660254037844388, -0.4999999999999997), (-0.2500000000000002, -0.4330127018922192), (-1.8369701987210297e-16, -1.0), (0.24999999999999967, -0.4330127018922195), (0.8660254037844384, -0.5000000000000004), (0.5, -1.2246467991473532e-16)]
X = np.array([-0.10885458,  0.38719084,  0.126246  ,  0.32831633, -0.43470323,
       -0.14589308,  0.03527489, -0.30802489,  0.03631802, -0.6407443 ,
        0.1420586 , -0.04242902,  0.56713419,  0.03697127,  0.56324232,
       -0.17307027,  0.23414952, -0.1249898 ,  0.10993816, -0.15574171,
        0.22480668, -0.16938372,  0.46415079,  0.05454076,  0.63360403,
       -0.43812225,  0.39817569, -0.31963035, -0.31926434,  0.16913435,
        0.68687168, -0.14839105,  0.53042922, -0.04944691, -0.20848955,
        0.60348851, -0.23746634, -0.00968032, -0.63404439, -0.05204527,
        0.27697056, -0.0023835 , -0.60480204, -0.29335925,  0.08750121,
        0.13853292,  0.01434203, -0.51095204,  0.17537239, -0.21610341])
Y = np.array([-0.10566327,  0.36444335,  0.50664288,  0.34520176,  0.12666237,
        0.24523639,  0.45936775,  0.36855297, -0.89093646,  0.25080176,
       -0.21871761,  0.56413549, -0.37842424, -0.85040143,  0.28691973,
       -0.02916441,  0.20025945, -0.25469069,  0.52055077, -0.23973923,
       -0.03349382, -0.4850852 , -0.22147722,  0.82357372,  0.19736351,
        0.16366808, -0.30763208, -0.07932644,  0.18458957,  0.19116663,
       -0.37589083, -0.62173701, -0.08265561,  0.28642521, -0.3096187 ,
        0.18280694,  0.0287418 , -0.35277588,  0.41465303,  0.77087622,
       -0.20084426,  0.72120447, -0.29936638,  0.39579946,  0.35693334,
        0.41785566, -0.39066645,  0.01689062,  0.25396642,  0.12154352])
Z = np.array([0.36857377, 0.08481739, 0.08529314, 0.09577443, 0.12750615,
       0.22158901, 0.18614892, 0.0703758 , 0.0111191 , 0.03745636,
       0.24347694, 0.13703608, 0.08855241, 0.03235803, 0.11979384,
       0.33964959, 0.23354923, 0.23385712, 0.09479431, 0.22835837,
       0.29181292, 0.0550857 , 0.15981413, 0.02425207, 0.01008352,
       0.14666378, 0.14105369, 0.20266958, 0.25451451, 0.25561241,
       0.07160838, 0.0181599 , 0.02512438, 0.25329402, 0.14160124,
       0.02455915, 0.275493  , 0.25261528, 0.05976918, 0.04502752,
       0.23377016, 0.11031544, 0.09229812, 0.04252507, 0.1807899 ,
       0.11100155, 0.23271334, 0.00184005, 0.19467501, 0.31437854])

# 生成星形边界路径,用于区域掩码
star_path = Path(coords)

# 生成高密度规则插值网格
x_min, x_max = -1.1, 1.1
y_min, y_max = -1.1, 1.1
grid_res = 300
xi, yi = np.meshgrid(np.linspace(x_min, x_max, grid_res),
                     np.linspace(y_min, y_max, grid_res))

# 判断网格点是否在星形区域内部
grid_points = np.vstack([xi.flatten(), yi.flatten()]).T
in_region_mask = star_path.contains_points(grid_points).reshape(xi.shape)

# 基于采样点做三角插值
tri = Triangulation(X, Y)
interp = LinearTriInterpolator(tri, Z)
zi = interp(xi, yi)

# 将区域外的插值结果设为空值,不参与绘制
zi[~in_region_mask] = np.nan

# 绘制图形
plt.figure(figsize=(7,7), dpi=100)
# 绘制平滑热力图
heatmap = plt.pcolormesh(xi, yi, zi, cmap='viridis', shading='gouraud')
# 绘制白色星形边界
bound_x, bound_y = zip(*coords)
plt.plot(bound_x, bound_y, color='white', linewidth=2)
# 可选:叠加原始采样点
plt.scatter(X, Y, s=15, color='white', edgecolor='black', zorder=3)
# 添加色条
plt.colorbar(heatmap, label='Z值')
# 设置等比例坐标轴避免星形变形
plt.gca().set_aspect('equal')
plt.xlim(x_min, x_max)
plt.ylim(y_min, y_max)
plt.axis('off')
plt.show()

调参说明

  • 配色修改:替换pcolormesh的cmap参数即可,彩虹热力图用cmap='jet',感知均匀配色用cmap='viridis'
  • 平滑度调整:将线性插值器LinearTriInterpolator替换为CubicTriInterpolator即可得到三次平滑插值结果,色彩过渡更自然
  • 图形样式:需要显示坐标轴就删除plt.axis('off'),不需要显示采样点就删除对应的scatter代码
  • 等值线效果:将pcolormesh替换为contourf,可自定义levels参数调整等值线层级
  • 该方案可适配任意不规则多边形区域,包括带孔洞的复杂区域,仅需在Path对象中补充对应孔洞的路径定义即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 12:54:18