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

如何在Matplotlib 3D图的X/Y轴使用日期数据并解决qhull报错

报错原因

  • 触发qhull Delaunay triangulation calculation: singular input data错误的核心原因是:plot_trisurf要求输入的X、Y样本点在X-Y平面上覆盖一片连续区域,不能完全共线的点无法执行三角剖分。你提供的示例代码中,date1和date2是固定偏移14天的等间隔序列,所有(date1, date2)坐标点严格落在同一条直线上,不符合算法输入要求。
  • 代码还存在几处语法问题:
    • 创建画布时使用plt.figure(),后续创建3D轴时调用了未定义的fig变量
    • 未导入cm模块就直接使用cm.coolwarm
    • 刻度定位用的some_dates变量未定义

解决方法

要绘制trisurf、plot_surface类3D曲面,需要先将输入数据调整为二维网格结构,覆盖X-Y平面的连续区域,而非逐行配对的一维共线点。修改后的可运行代码如下:

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.dates as dates
import matplotlib.ticker as ticker
import pandas as pd
from matplotlib import cm

# 生成覆盖二维区域的日期序列
date1_all = pd.date_range(start='2018-01-05', end='2018-01-20', freq='1D')
date2_all = pd.date_range(start='2018-01-19', end='2018-02-03', freq='1D')
# 生成二维网格
date1_grid, date2_grid = np.meshgrid(date1_all, date2_all)
# 生成对应网格的测量值(模拟真实业务数据
z_data = np.sin(2*np.linspace(-1,1,date1_grid.size)).reshape(date1_grid.shape) + np.cos(2*np.linspace(-1,1,date2_grid.size).reshape(date2_grid.shape)

def format_date(x, pos=None):
    return dates.num2date(x).strftime('%Y-%m-%d')

# 创建画布与3D轴
fig = plt.figure(figsize=(10,7))
ax = Axes3D(fig, rect=[0,0.1,1,1])

# 两种绘图方式二选一即可
# 方式1:plot_surface绘制曲面
ax.plot_surface(dates.date2num(date1_grid), dates.date2num(date2_grid), z_data, cmap=cm.coolwarm, linewidth=0.2)
# 方式2:plot_trisurf绘制三角曲面,需将网格展平为一维
# ax.plot_trisurf(dates.date2num(date1_grid.flatten()), dates.date2num(date2_grid.flatten()), z_data.flatten(), cmap=cm.coolwarm, linewidth=0.2)

# 配置日期刻度,按间隔3个日期显示一个刻度
some_dates_x = dates.date2num(date1_all[::3])
ax.w_xaxis.set_major_locator(ticker.FixedLocator(some_dates_x))
ax.w_xaxis.set_major_formatter(ticker.FuncFormatter(format_date))
some_dates_y = dates.date2num(date2_all[::3])
ax.w_yaxis.set_major_locator(ticker.FixedLocator(some_dates_y))
ax.w_yaxis.set_major_formatter(ticker.FuncFormatter(format_date))

# 调整刻度标签显示角度
for tl in ax.w_xaxis.get_ticklabels():
    tl.set_ha('right')
    tl.set_rotation(30)
for tl in ax.w_yaxis.get_ticklabels():
    tl.set_ha('right')
    tl.set_rotation(-30)

ax.set_xlabel('date1')
ax.set_ylabel('date2')
ax.set_zlabel('mydata')

plt.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 18:57:00