如何用Python绘制带孔洞(缺失值)的2D彩色平滑曲面图?
实现带孔洞的无插值2D彩色曲面图方案
需求回顾
现有一维坐标数据(x、y)和对应的颜色值z,需要绘制2D彩色曲面图,满足:
- 保留x值间距大于2的孔洞区域
- 不进行任何数据插值
- 替代当前的散点图,实现连续的彩色曲面效果
数据处理与实现思路
- 拆分数据段:先找出x间距大于2的位置,将数据拆分为两个连续的子集,避免跨孔洞连接面元
- 构建面元:对每个连续数据段,将相邻点与下方的基准线连接成四边形面元,每个面元的颜色对应原始z值(或相邻z值的平均,完全无插值)
- 绘制与配色:用
PolyCollection加载所有面元,映射z值到指定配色方案,添加颜色条
完整代码实现
import matplotlib.pyplot as plt import numpy as np from matplotlib.collections import PolyCollection # 原始数据转换为numpy数组 x = np.array([23.0757, 23.8643, 24.6545, 25.4138, 27.7498, 28.5586, 29.3396, 30.079, 30.8425, 31.6162, 32.3812]) y = np.array([11.3574, 11.1981, 11.0303, 10.8517, 10.2982, 10.1016, 9.8989, 9.7036, 9.4833, 9.2579, 9.0362]) z = np.array([15.1817, 15.0578, 13.9388, 12.8876, 13.0838, 12.1634, 10.6768, 9.6899, 9.712, 9.8358, 9.5188]) # 拆分数据:找到x间距大于2的分割点 split_idx = np.where(np.diff(x) > 2)[0][0] + 1 data_segments = [ (x[:split_idx], y[:split_idx], z[:split_idx]), (x[split_idx:], y[split_idx:], z[split_idx:]) ] fig, ax = plt.subplots(figsize=(8, 6)) polygon_list = [] color_values = [] # 设置曲面底边的偏移量(可根据需求调整) bottom_y_offset = 0.5 for seg_x, seg_y, seg_z in data_segments: # 确定当前段的底边y值(低于当前段最小y值) bottom_y = seg_y.min() - bottom_y_offset # 遍历相邻点,构建四边形面元 for i in range(len(seg_x) - 1): # 四边形顶点顺序:左上→右上→右下→左下 polygon = [ (seg_x[i], seg_y[i]), (seg_x[i+1], seg_y[i+1]), (seg_x[i+1], bottom_y), (seg_x[i], bottom_y) ] polygon_list.append(polygon) # 用相邻两点z值的平均值作为面元颜色(完全无插值可直接用seg_z[i]) color_values.append((seg_z[i] + seg_z[i+1]) / 2) # 创建面元集合并映射颜色 poly_collection = PolyCollection(polygon_list, cmap='jet') poly_collection.set_array(np.array(color_values)) ax.add_collection(poly_collection) # 添加颜色条 plt.colorbar(poly_collection, label='z值') # 调整坐标轴范围,确保图形完整显示 ax.set_xlim(x.min() - 0.3, x.max() + 0.3) ax.set_ylim(y.min() - bottom_y_offset - 0.2, y.max() + 0.2) # 设置坐标轴标签 ax.set_xlabel('x') ax.set_ylabel('y') plt.show()
关键说明
- 孔洞保留:通过拆分数据段,两段数据之间不会生成面元,自然形成孔洞
- 无插值保证:所有面元的颜色直接来自原始z值(或相邻z值平均,未引入额外插值点)
- 曲面形状调整:可通过修改
bottom_y_offset参数调整曲面的垂直宽度,适配需求
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

