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

matplotlib绘制3D曲面时qhull Delaunay三角剖分错误如何解决

错误成因
  • 数据读取逻辑错误:你使用np.genfromtxt读取带4个字段的结构化数组后,直接用zip(*data)解包会得到4组序列(对应x/y/z/k四个字段),赋值给x/y/z三个变量时会出现隐式截断,把k字段的值混入z轴数据,导致输入给三角剖分的坐标数据完全错乱。
  • 输入数据不符合Delaunay三角剖分要求:plot_trisurf依赖qhull库对xy平面的点做三角剖分,若数据中存在重复的(x,y)坐标、共线点过多、存在空值,都会触发剖分失败的报错。
  • 分类变量未做分组处理:你的数据中包含取值为0/1的分类变量k,不同k类的样本混在一起绘制曲面,会导致xy平面的点分布不符合连续曲面的剖分逻辑。
修复方案

首先修正数据读取逻辑,提前做数据清洗,可根据需求选择两种绘图方案:

方案1:按k值分组绘制三角曲面(保留原始数据分布)

修复后的代码如下:

import numpy as np
import matplotlib.pyplot as plt

# 修正数据读取逻辑,直接提取对应字段
data = np.genfromtxt("data.csv", delimiter=",", names=["x", "y","z","k"])
x = data['x']
y = data['y']
z = data['z']
k = data['k']

# 数据清洗:去除空值、去重xy重复的点
valid_mask = ~np.isnan(x) & ~np.isnan(y) & ~np.isnan(z)
x, y, z, k = x[valid_mask], y[valid_mask], z[valid_mask], k[valid_mask]
# 去重:保留每个(x,y)坐标的第一个样本
_, unique_idx = np.unique(np.column_stack((x, y)), axis=0, return_index=True)
x, y, z, k = x[unique_idx], y[unique_idx], z[unique_idx], k[unique_idx]

# 按k值分组绘图
fig = plt.figure(figsize=(12,6))
for idx, k_val in enumerate([0,1]):
    mask = k == k_val
    x_k, y_k, z_k = x[mask], y[mask], z[mask]
    ax = fig.add_subplot(1, 2, idx+1, projection='3d')
    ax.set_xlabel('X')
    ax.set_ylabel('Y')
    ax.set_zlabel('Optimal-Selection')
    ax.set_xlim(0,1)
    ax.set_ylim(0,1)
    ax.set_zlim(0,1)
    ax.set_title(f'k = {k_val}')
    surf = ax.plot_trisurf(x_k, y_k, z_k, cmap='viridis')
    fig.colorbar(surf, shrink=0.5, aspect=9, ax=ax)

plt.show()

方案2:插值生成规则网格后绘制曲面(更平滑,无剖分错误)

如果分组后仍然存在三角剖分错误,可以先对数据做二维插值生成规则网格再绘图,代码如下:

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

data = np.genfromtxt("data.csv", delimiter=",", names=["x", "y","z","k"])
x = data['x']
y = data['y']
z = data['z']
k = data['k']

valid_mask = ~np.isnan(x) & ~np.isnan(y) & ~np.isnan(z)
x, y, z, k = x[valid_mask], y[valid_mask], z[valid_mask], k[valid_mask]

# 生成0-1区间的规则网格
xi = np.linspace(0, 1, 100)
yi = np.linspace(0, 1, 100)
xi, yi = np.meshgrid(xi, yi)

fig = plt.figure(figsize=(12,6))
for idx, k_val in enumerate([0,1]):
    mask = k == k_val
    x_k, y_k, z_k = x[mask], y[mask], z[mask]
    # 插值得到网格对应的z值
    zi = griddata((x_k, y_k), z_k, (xi, yi), method='cubic')
    ax = fig.add_subplot(1, 2, idx+1, projection='3d')
    ax.set_xlabel('X')
    ax.set_ylabel('Y')
    ax.set_zlabel('Optimal-Selection')
    ax.set_xlim(0,1)
    ax.set_ylim(0,1)
    ax.set_zlim(0,1)
    ax.set_title(f'k = {k_val}')
    surf = ax.plot_surface(xi, yi, zi, cmap='viridis')
    fig.colorbar(surf, shrink=0.5, aspect=9, ax=ax)

plt.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 16:30:05