3D曲面图X、Y轴交换实现:滚动相关性曲面绘制形状不匹配错误排查求助
解决3D滚动相关性曲面图的形状不匹配问题
你遇到的ValueError: shape mismatch核心原因是X、Y网格的形状和Z数据的形状不匹配,咱们一步步拆解问题并修正:
错误根源分析
你的原始DataFrame st 的结构是:
- 行:日期(3条记录,形状
(3,)) - 列:滚动周期(4个周期,形状
(4,)) - Z数据(
st.values)的形状是(3,4)
当你执行x, y = np.meshgrid(st.index, st.columns)时:
x的形状会变成(4,3)(meshgrid把y轴的周期作为第一维度,x轴的日期作为第二维度)y的形状同样是(4,3)
但你的Z数据还是(3,4),和X/Y的形状不匹配,自然会报错。
另外还有个小问题:datetime类型的日期直接作为3D轴的数值输入容易出问题,建议先把日期转换成可计算的数值(比如序数ordinal)。
修正后的代码
import pandas as pd import numpy as np import matplotlib.pyplot as plt from matplotlib import cm # 构造示例数据 st = {'10': [-0.2,0.4,0.1], '20': [0.6,0.3,0], '30': [-0.4,0.6,0.2], '40': [0.1,0.2,0.4]} st = pd.DataFrame(data=st) st.index = pd.date_range("20200101", periods=3) # 绘制3D曲面图 fig = plt.figure(figsize=(12,10)) ax = fig.add_subplot(projection='3d') # 1. 将日期转为序数(数值类型),方便3D绘图处理 x_dates_num = st.index.to_series().apply(lambda d: d.toordinal()) y_periods = st.columns.astype(int) # 将周期转为整数类型 # 2. 生成网格:X是日期数值,Y是周期 X, Y = np.meshgrid(x_dates_num, y_periods) # 3. 转置Z数据,让形状和X/Y匹配(原st是(3,4),转置后是(4,3)) Z = st.values.T # 4. 绘制曲面 ax.plot_surface(X, Y, Z, cmap=cm.coolwarm, linewidth=0, antialiased=False) # 5. 设置轴刻度和标签 # X轴:还原日期刻度 ax.set_xticks(x_dates_num) ax.set_xticklabels(st.index.strftime('%Y-%m-%d')) # Y轴:设置周期刻度 ax.set_yticks(y_periods) ax.set_yticklabels(y_periods) # 添加轴标签 ax.set_xlabel('日期') ax.set_ylabel('滚动周期(天)') ax.set_zlabel('滚动相关性') plt.show()
关键修改点说明
- 日期转数值:用
toordinal()把datetime对象转换成整数,避免3D绘图对非数值类型的兼容问题 - Z数据转置:
st.values.T将原数据的行/列反转,让Z的形状(4,3)和X/Y的(4,3)完全匹配 - 轴刻度设置:分别给X/Y轴设置对应的原始标签,保证图表可读性
这样就能得到你想要的:日期在X轴,滚动周期在Y轴的3D曲面图啦。
内容的提问来源于stack exchange,提问作者eyrie01




